http://poj.org/problem?id=2049 /* 我认为这是一道非常好的搜索题, 第一次使用到了优先队列,(是更新的距离最短),0代表空 1代表 们 inf 代表wall 用h[][] 存储行的信息,l[][],存储列的信息 {学到的新知识,对于这种一方格作为点的 图 用两个二维图分别存储变得信息} */ #include<cstdio> #include<cstring> #include<queue> using namespace std; #define maxn 250 #define inf 99999999 struct node { int x; int y; int len; bool operator <(const node &a)const { return len>a.len; } }; int n,m,sx,sy,xmax,ymax; int dis[maxn][maxn],h[maxn][maxn],l[maxn][maxn]; priority_queue<node>q; void bfs() { int x,y; for(x=0;x<=xmax;x++) { for(y=0;y<=ymax;y++) { dis[x][y]=inf; } } while(!q.empty())q.pop(); node pn; pn.x=0;pn.y=0;pn.len=0; dis[0][0]=0; q.push(pn); while(!q.empty()) { pn=q.top(); q.pop(); x=pn.x;y=pn.y; if(x==sx&&y==sy)return ; //向上走 if(y+1<=ymax&&dis[x][y+1]>dis[x][y]+h[x][y+1]) { dis[x][y+1]=dis[x][y]+h[x][y+1]; pn.x=x;pn.y=y+1;pn.len=dis[x][y+1]; q.push(pn); } //向下走 if(y-1>=0&&dis[x][y-1]>dis[x][y]+h[x][y]) { dis[x][y-1]=dis[x][y]+h[x][y]; pn.x=x;pn.y=y-1;pn.len=dis[x][y-1]; q.push(pn); } //想左走 if(x-1>=0&&dis[x-1][y]>dis[x][y]+l[x][y]) { dis[x-1][y]=dis[x][y]+l[x][y]; pn.x=x-1;pn.y=y;pn.len=dis[x-1][y]; q.push(pn); } //向右走 if(x+1<=xmax&&dis[x+1][y]>dis[x][y]+l[x+1][y]) { dis[x+1][y]=dis[x][y]+l[x+1][y]; pn.x=x+1;pn.y=y;pn.len=dis[x+1][y]; q.push(pn); } } dis[sx][sy]=-1; } int main() { int i,j,x,y,d,t; double tx,ty; while(scanf("%d%d",&n,&m)!=EOF) { if(m==-1&&n==-1)break; xmax=ymax=-1; memset(h,0,sizeof(h)); memset(l,0,sizeof(l)); for(i=0;i<n;i++) { scanf("%d%d%d%d",&x,&y,&d,&t); if(d==0) { for(j=0;j<t;j++) { h[x+j][y]=inf; } xmax=max(xmax,x+t); ymax=max(ymax,y); } else { for(j=0;j<t;j++) { l[x][y+j]=inf; } xmax=max(xmax,x); ymax=max(ymax,y+t); } } for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&d); if(d==0) { h[x][y]=1; } else l[x][y]=1; } scanf("%lf%lf",&tx,&ty); if(tx>xmax||ty>ymax) { printf("0\n"); } else { sx=(int)tx; sy=(int)ty; bfs(); printf("%d\n",dis[sx][sy]); } } }