鏈接:http://poj.org/problem?id=2049
將座標系轉爲格子圖,兩點之間可能有牆,或者門,也可能什麼都沒有,沒有的花費爲0,門的花費爲1,問到目標點的最少花費是多少
注意題目中的輸入範圍,
四位二進制表示下點四周的邊牆情況,然後bfs更新下各點最優值。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <string>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 309
#define MAXM 50007
struct node
{
int x, y;
int ans;
};
queue<node> q;
//int vis_mp[MAXN][MAXN];
int vis[MAXN*MAXN*2];
int vp[MAXN*MAXN*2];
int dis[5];
int dis_4[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
double xx,yy;
int Ans[MAXN][MAXN];
int main()
{
int n,m;
for(int i=0; i<4; ++i)
dis[i]=(1<<i);//cout<<dis[i]<<endl;
// int ppp=0;
// for(int i=0; i<4; ++i)
// ppp|=(1<<i);
// cout<<ppp<<endl;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==-1)break;
int x,y,c,d;
memset(vp,0,sizeof(vp));
memset(vis,0,sizeof(vis));
// memset(vis_mp,0,sizeof(vis_mp));
memset(Ans,INF,sizeof(Ans));
for(int i=0; i<n; ++i)
{
scanf("%d%d%d%d",&x,&y,&c,&d);
if(c==0)
{
int pa=y*MAXN+x;
int pb=(y-1)*MAXN+x;
for(int j=0; j<d; ++j)
{
vp[pa++]|=dis[2];
vp[pb++]|=1;
}
}
else
{
int pa=y*MAXN+x;
int pb=pa-1;
for(int j=0; j<d; ++j)
{
vp[pa]|=dis[3];
vp[pb]|=dis[1];
pa+=MAXN;
pb+=MAXN;
}
}
}
for(int i=0; i<m; ++i)
{
scanf("%d%d%d",&x,&y,&c);
if(c==0)
{
int pa=y*MAXN+x;
int pb=(y-1)*MAXN+x;
vis[pa]|=dis[2];
vis[pb]|=1;
}
else
{
int pa=y*MAXN+x;
int pb=pa-1;
vis[pa]|=dis[3];
vis[pb]|=dis[1];
}
}
scanf("%lf%lf",&xx,&yy);
int xa=xx,yb=yy;
if(xa<1||yb<1||xa>199||yb>199)
{
printf("0\n");
continue;
}
node st;
st.x=0,st.y=0;
st.ans=0;
Ans[0][0]=0;
// vis_mp[0][0]=1;
while(!q.empty())q.pop();
q.push(st);
while(!q.empty())
{
node u=q.front();
q.pop();
int ip=u.y*MAXN+u.x;
for(int i=0; i<4; ++i)
{
int xk=u.x+dis_4[i][0];
int yk=u.y+dis_4[i][1];
if(xk>=MAXN ||yk>=MAXN||xk<0||yk<0)continue;
// if(vis_mp[xk][yk])continue;
node nep;
nep.x=xk;
nep.y=yk;
if(!(vp[ip]&dis[i]))
{
nep.ans=u.ans;
if(Ans[xk][yk]>nep.ans)
{
Ans[xk][yk]=nep.ans;
q.push(nep);
}
continue;
}
if(vis[ip]&dis[i])
{
nep.ans=u.ans+1;
if(Ans[xk][yk]>nep.ans)
{
Ans[xk][yk]=nep.ans;
q.push(nep);
}
continue;
}
}
}
/*
cout<<endl;
for(int i=0; i<=5; ++i)
{
for(int j=0; j<=5; ++j)
cout<<vis[i*MAXN+j]<<" ";
cout<<endl;
}
cout<<endl;
for(int i=0; i<=5; ++i)
{
for(int j=0; j<=5; ++j)
cout<<vp[i*MAXN+j]<<" ";
cout<<endl;
}
// cout<<vis[0]<<" "<<vis[MAXN]<<endl;
// cout<<vp[MAXN+1]<<" "<<vis[MAXN+1]<<endl;
cout<<endl;
for(int i=0; i<=5; ++i)
{
for(int j=0; j<=5; ++j)
cout<<Ans[i][j]<<" ";
cout<<endl;
}
*/
if(Ans[xa][yb]==INF)printf("-1\n");
else printf("%d\n",Ans[xa][yb]);
}
return 0;
}
/*
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
*/