将行与列都抽象为点 对于每一行或者列 把所有与其有接触的点都挂到上边 一入一出的权值为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;
}