HDU 1198 Farm Irrigation

来源:互联网 发布:现在有什么网络歌曲 编辑:程序博客网 时间:2024/06/10 22:30

传送门:HDU1198

题意:浇灌田地,图中的蓝色的线代表水管,水管能连起来的用一个泉源即可浇灌,问浇灌这片田地用需要多少个泉源

题解:并查集,将两个能用管子连起来的田地关联起来,变型成并查集模式

代码:

#include <iostream>#include <cstdio>using namespace std;char shape[15][15]={"1010","1001","0110","0101",                    "1100","0011","1011","1110",                    "0111","1101","1111"};//上下左右,给方块赋初值int father[2505];char Map[55][55];int n,m;int Find(int x)//并查集部分的查找函数{    if(x==father[x])        return x;    return Find(father[x]);}void Union(int x,int y)//并查集部分的关联函数{    int xx=Find(x);    int yy=Find(y);    father[xx]=yy;}void sovle(){    int i,j,k,a,b;    for(i=0,k=1;i<n;i++)//每个方块循环判断能否和相邻方块链接    {        for(j=0;j<m;j++)        {            a=(int)Map[i][j]-65;            if(i!=0)//判断上方            {                b=(int)Map[i-1][j]-65;                if(shape[a][0]=='1'&&shape[b][1]=='1')//如果能链接,进行关联,下同                    Union(k,k-m);            }            if(i!=n-1)//判断下方            {                b=(int)Map[i+1][j]-65;                if(shape[a][1]=='1'&&shape[b][0]=='1')                    Union(k,k+m);            }            if(j!=0)//判断左方            {                b=(int)Map[i][j-1]-65;                if(shape[a][2]=='1'&&shape[b][3]=='1')                    Union(k,k-1);            }            if(j!=m-1)//判断右方            {                b=(int)Map[i][j+1];                if(shape[a][3]=='1'&&shape[b][2]=='1')                    Union(k,k+1);            }            k++;        }    }}int main(){    int i,j,k,ans;    while(~scanf("%d%d",&n,&m)&&(n!=-1&&m!=-1))    {        for(i=0;i<n;i++)        scanf("%s",Map[i]);        for(i=0,k=1;i<n;i++)            for(j=0;j<m;j++)            {                father[k]=k;                k++;            }        sovle();        for(i=1,ans=0;i<=n*m;i++)            if(father[i]==i) ans++;        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击