HDU 1198 Farm Irrigation (並查集優化,構圖)
阿新 • • 發佈:2017-06-09
++ space int con can 組成 union trac 輸入
本題和HDU暢通project類似。僅僅只是暢通project給出了數的連通關系,
而此題須要自己推斷連通關系,即兩個水管能否夠連接到一起,也是本題的難點所在。
記錄狀態。不斷combine(),註意僅僅須要推斷左方和上方即可,這樣不會反復推斷,並且肯定都能夠遍歷到全部的狀態。
#include<stdio.h> #include<iostream> #include<string> //記錄水管的形狀,每種水管用一個由‘0‘和‘1‘組成的長度為4的字符串代表, //分別表示上下左右四邊是否有接口,‘0‘無,‘1‘有 char a[11][5]={"1010","1001","0110","0101","1100","0011", "1011","1110","0111","1101","1111"}; int father[51][51]; char map[51][51]; int n,m; using namespace std; int find(int x)//查找父節點,並壓縮路徑 { if(father[x/n][x%n]!=x) father[x/n][x%n]=find(father[x/n][x%n]); return father[x/n][x%n]; } void Union(int x,int y)//合並x,y的集合 { x=find(x); y=find(y); if(x!=y) father[y/n][y%n]=x; } void judge(int i,int j)//推斷map[i][j]和它的左側和上側是否連通,如連通則合並 { if(j>0&&a[map[i][j]-‘A‘][2]==‘1‘&&a[map[i][j-1]-‘A‘][3]==‘1‘)//推斷上方 Union(i*n+j,i*n+j-1); if(i>0&&a[map[i][j]-‘A‘][0]==‘1‘&&a[map[i-1][j]-‘A‘][1]==‘1‘)//推斷左方 Union(i*n+j,(i-1)*n+j); } int main() { int i,j,count; while(scanf("%d%d",&m,&n)!=-1&&(n!=-1||m!=-1)) { for(i=0;i<m;i++) { scanf("%s",map[i]);//輸入矩陣 for(j=0;j<n;j++) father[i][j]=i*n+j;//將父節點初始化 } for(i=0;i<m;i++) for(j=0;j<n;j++) judge(i,j); count=0;//查找父節點是本身的點的個數。即共同擁有幾個集合 for(i=0;i<m;i++) for(j=0;j<n;j++) if(father[i][j]==i*n+j) count++; printf("%d\n",count); } return 0; }
HDU 1198 Farm Irrigation (並查集優化,構圖)