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 }
人生就像心电图,想要一帆风顺,除非game-over