hdu1198 Farm Irrigation —— dfs or 并查集

来源:互联网 发布:什么是scratch编程 编辑:程序博客网 时间:2024/05/18 00:59

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198


dfs:

#include<cstdio>//hdu1198 dfs#include<cstring>int well[11][5] = { {1,1,1,0,0},{1,0,1,1,0},{0,1,1,0,1},{0,0,1,1,1},{1,0,1,0,1},{0,1,1,1,0},{1,1,1,1,0},{1,1,1,0,1},{0,1,1,1,1},{1,0,1,1,1},{1,1,1,1,1}};const int ca[5][2] = {0,1,1,0,1,1,1,2,2,1}, mov[4][2] = {1,0,-1,0,0,1,0,-1};int m,n,sum, map[550][550],id[550][550];void build(int set, int x, int y){    for(int k = 0; k<5; k++)    {        if(well[set][k])        {            map[3*x+ca[k][0]][3*y+ca[k][1]] = 1;        }    }}void dfs(int x, int y, int iden){    id[x][y] = iden;    for(int i = 0; i<4; i++)    {        int xx = x + mov[i][0], yy = y + mov[i][1];        if(xx<0 || xx>3*m-1 || yy<0 || yy>3*n-1 ) continue;        if(map[xx][yy] && !id[xx][yy])        dfs(xx,yy,iden);    }}int main(){    char init[5005];    while(scanf("%d%d",&m,&n) && (m!=-1 || n!=-1 ))    {        memset(map,0,sizeof(map));        memset(id,0,sizeof(id));        for(int i = 0; i<m; i++)        {            scanf("%s",init);            for(int j = 0; j<n; j++)            build(init[j]-65,i,j);        }        sum = 0;        for(int i = 0; i<=3*m-1; i++)        {            for(int j = 0; j<=3*n-1; j++)            {                //printf("%d ",map[i][j]);                if(map[i][j] && !id[i][j])                {                    dfs(i,j,++sum);                }            }            //putchar('\n');        }        printf("%d\n",sum);    }    return 0;}



并查集:

#include<cstdio>//hdu1198 并查集 每个格子的标号为i*n+j,初始father也为i*n+j,以次来作为合并集合的依据#include<cstring>int n,m,father[55][55];char map[55][55];char type[11][5]={"1010","1001","0110","0101","1100","0011",               "1011","1110","0111","1101","1111"};int find(int x){    return (x==father[x/n][x%n])?x:find(father[x/n][x%n]);}int unit(int a, int b){    a = find(a);    b = find(b);    if(a!=b)//合并集合        father[a/n][a%n] = b;}int judge(int i, int j){   //判断是否与左边相连    if(j>0 && type[map[i][j]-'A'][2]=='1' && type[map[i][j-1]-'A'][3]=='1')        unit(i*n+j,i*n+j-1);    //判断是否与上边相连    if(i>0 && type[map[i][j]-'A'][0]=='1' && type[map[i-1][j]-'A'][1]=='1')        unit(i*n+j,(i-1)*n+j);}int main(){    while(scanf("%d%d",&m,&n) && (m!=-1 || n!=-1))    {        for(int i = 0; i<m; i++)        {            scanf("%s",&map[i]);            for(int j = 0; j<n; j++)            {   //初始化为自己                father[i][j] = i*n+j;            }        }                //并查集过程        for(int i = 0; i<m; i++)        for(int j = 0; j<n; j++)        judge(i,j);        int sum = 0;        for(int i = 0; i<m; i++)        for(int j = 0; j<n; j++)//看看有多少个“根节点”            if(father[i][j]==i*n+j) sum++;        printf("%d\n",sum);    }}



0 0