HDU-5652 India and China Origins(并查集)

来源:互联网 发布:自响应留言板php 编辑:程序博客网 时间:2024/06/01 10:28

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=5652

题意:

两国之间有一个n*m的棋盘,中间一开始有一些山脉,后来每年新增一个山脉,求两国第一次被彻底隔绝的时间。未被隔绝返回-1。

思路:

500*500的大小,可以展开成250000个节点求并查集,先把所有的山脉都放上去,然后处理一下并查集,就是每个节点和旁边的4个节点是否都是平地,是就连通。最后再新增两个节点代表两国,第一排和最后一排的节点与之联通。然后倒叙删掉新增的山脉,并查集寻找合适能够联通。答案就是当前年份加一。

代码:

//kopyh#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define MOD 1000000007#define EPS 1e-6#define N 1123456using namespace std;int n,m,sum,res,flag;int a[N],b[N];char s[N];int f[N],g[510][510];int dir[4][2]={1,0,0,1,-1,0,0,-1};void init(int n){    for(int i=1;i<=n;i++)f[i]=i;}int getf(int v){    while(f[v] != v)    {        f[v]=f[f[v]];        v = f[v];    }    return f[v];}void unions(int x,int y){    x = getf(x);    y = getf(y);    if(x == y) return;    f[y] = x;}int main(){    int i,j,k,kk,cas,T,t,x,y,z;    scanf("%d",&T);    cas=0;    while(T--)    {        scanf("%d%d",&n,&m);        for(i=0;i<n;i++)        {            scanf("%s",s);            for(j=0;j<m;j++)                g[i][j]=s[j]-'0';        }        scanf("%d",&sum);        for(i=1;i<=sum;i++)        {            scanf("%d%d",&a[i],&b[i]);            g[a[i]][b[i]]=1;        }        init(n*m+2);        for(i=0;i<n;i++)            for(j=0;j<m;j++)                if(!g[i][j])                    for(k=0;k<4;k++)                    {                        x=i+dir[k][0];y=j+dir[k][1];                        if(x<0||y<0||x>=n||y>=m)continue;                        if(!g[x][y])                            unions(i*m+j,x*m+y);                        if(i==0)                            unions(i*m+j,n*m);                        if(i==n-1)                            unions(i*m+j,n*m+1);                    }        res=sum;        while(getf(n*m)!=getf(n*m+1))        {            i=a[res];j=b[res];            g[i][j]=0;            for(k=0;k<4;k++)            {                x=i+dir[k][0];y=j+dir[k][1];                if(x<0||y<0||x>=n||y>=m)continue;                if(!g[x][y])                    unions(i*m+j,x*m+y);                if(i==0)                    unions(i*m+j,n*m);                if(i==n-1)                    unions(i*m+j,n*m+1);            }            res--;        }        printf("%d\n",res==sum?-1:res+1);    }    return 0;}









0 0