Okabe and City CodeForces - 821D

点击打开链接

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

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/80165548