HDU 1198(并查集)

题意:给你11个图,每一个都有管道,然后给一张由这11个正方形中的n个组成的图,判断有几条连通的管道;

思路:在大一暑假的时候做过这道题,当时是当暴力来做的,正解是并查集,需要进行一下转换;

转换1:将子图中的管道转换为数字码,通为1,不通为0;

转换2:一维--->二维,i,j换成在n*m中的第几个,p[i][j] = i*n+j,而且find_set,Union也需要独一无二的坐标来进行判断,然后转换成2维去具体比较;

 1 #include<stdio.h>
 2 char a[11][5]= {"1010","1001","0110","0101","1100","0011","1011","1110","0111","1101","1111"};
 3 int p[51][51];
 4 char G[51][51];
 5 int n,m;
 6 int find_set(int x)///查找父节点,并压缩路径
 7 {
 8     int r = x/n;
 9     int c = x % n;
10     if(p[r][c]!=x)
11         p[r][c]=find_set(p[r][c]);
12     return p[r][c];
13 }
14 void Union(int x,int y)///合并x,y的集合
15 {
16     x=find_set(x);
17     y=find_set(y);
18     if(x!=y)
19         p[y/n][y%n]=x;
20 }
21 int main()
22 {
23     int i,j,sum;
24     while(scanf("%d%d",&m,&n)!=-1&&(n!=-1||m!=-1))
25     {
26         for(i=0; i<m; i++)
27         {
28             scanf("%s",G[i]);
29             for(j=0; j<n; j++)
30                 p[i][j]=i*n+j;///将父节点初始化
31         }
32         for(i=0; i<m; i++)
33             for(j=0; j<n; j++)
34             {
35                 ///判断两个方向就好了
36                 if(j>0&&a[G[i][j]-'A'][2]=='1'&&a[G[i][j-1]-'A'][3]=='1')
37                     Union(i*n+j,i*n+j-1);
38 
39                 if(i>0&&a[G[i][j]-'A'][0]=='1'&&a[G[i-1][j]-'A'][1]=='1')
40                     Union(i*n+j,(i-1)*n+j);
41             }
42         sum=0;
43         for(i=0; i<m; i++)
44             for(j=0; j<n; j++)
45                 if(p[i][j]==i*n+j)
46                     sum++;
47         printf("%d/n",sum);
48     }
49     return 0;
50 }
View Code

 

posted @ 2015-05-29 20:37  一麻袋码的玛侬  阅读(172)  评论(0编辑  收藏  举报