将行与列都抽象为点 对于每一行或者列 把所有与其有接触的点都挂到上边 一入一出的权值为1和0 相邻点再连权值为零的边即可
#include <bits/stdc++.h> using namespace std; #define N 0x3f3f3f3f struct node1 { int x; int y; }; struct node2 { int v; int w; int next; }; struct node3 { bool friend operator < (node3 n1,node3 n2) { return n1.val>n2.val; } int id; int val; }; priority_queue <node3> que; map <pair<int,int>,int> mp; node1 point[100010]; node2 edge[1000010]; int first[300010],dis[300010],book[300010]; int n,m,k,num; void addedge(int u,int v,int w) { edge[num].v=v; edge[num].w=w; edge[num].next=first[u]; first[u]=num++; return; } int dijkstra(int s,int e) { node3 cur,tem; int i,u,v,w; while(!que.empty()) que.pop(); memset(dis,0x3f,sizeof(dis)); memset(book,0,sizeof(book)); tem.id=s,tem.val=0; que.push(tem); dis[s]=0; while(!que.empty()) { cur=que.top(); que.pop(); u=cur.id; if(book[u]) continue; book[u]=1; for(i=first[u];i!=-1;i=edge[i].next) { v=edge[i].v,w=edge[i].w; if(!book[v]&&dis[v]>dis[u]+w) { dis[v]=dis[u]+w; tem.id=v,tem.val=dis[v]; que.push(tem); } } } if(dis[e]==N) return -1; else return dis[e]; } int main() { pair <int,int> p; int next[4][2]={0,-1,-1,0,0,1,1,0}; int i,j,x,y,tx,ty,flags,flage; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { mp.clear(); memset(first,-1,sizeof(first)); num=0,flags=0,flage=0; for(i=1;i<=k;i++) { scanf("%d%d",&point[i].x,&point[i].y); x=point[i].x,y=point[i].y; p=make_pair(x,y); mp[p]=i; if(x==1&&y==1) flags=i; if(x==n&&y==m) flage=i; addedge(i,x+k,1); addedge(x+k,i,0); addedge(i,y+n+k,1); addedge(y+n+k,i,0); if(x-1>=1) { addedge(i,x-1+k,1); addedge(x-1+k,i,0); } if(x+1<=n) { addedge(i,x+1+k,1); addedge(x+1+k,i,0); } if(y-1>=1) { addedge(i,y-1+n+k,1); addedge(y-1+n+k,i,0); } if(y+1<=m) { addedge(i,y+1+n+k,1); addedge(y+1+n+k,i,0); } } for(i=1;i<=k;i++) { x=point[i].x,y=point[i].y; for(j=0;j<4;j++) { tx=x+next[j][0]; ty=y+next[j][1]; if(tx<1||tx>n||ty<1||ty>m) continue; p=make_pair(tx,ty); if(mp[p]!=0) { p=make_pair(tx,ty); addedge(i,mp[p],0); } } } if(!flags) { flags=n+m+k+1; addedge(flags,1+k,1); addedge(1+k,flags,0); addedge(flags,1+n+k,1); addedge(1+n+k,flags,0); } if(!flage) { flage=n+m+k+2; addedge(flage,n+k,1); addedge(n+k,flage,0); addedge(flage,m+n+k,1); addedge(m+n+k,flage,0); } printf("%d\n",dijkstra(flags,flage)); } return 0; }