hdu 1198 Farm Irrigation
令人蛋疼的并查集……
我居然做了大量的枚举,居然过了,我越来越佩服自己了
这个题有些像一个叫做“水管工”的游戏。给你一个m*n的图,每个单位可以有11种选择,然后相邻两个图只有都和对方连接,才判断他们连接。然后找这里面有多少个连通图。
给大家一个一点也不高大上,但是一眼就能看懂的代码吧……
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 7 const int N = 55; 8 9 char mpc[N][N]; //第一次输入 10 bool mp[N*N][N*N]; //整理单向连通 11 bool mps[N*N][N*N]; //记录双向连通 12 int fm[N*N]; //并查集父节点,不用多说了吧…… 13 int m, n; 14 int sum; 15 16 void change2(int k, int x, int y) //四个方向连通 17 { 18 switch(k) 19 { 20 case 0: 21 if(x-1 >= 0) mp[x*m+y][(x-1)*m+y] = 1; break; 22 case 1: 23 if(y-1 >= 0) mp[x*m+y][x*m+y-1] = 1; break; 24 case 2: 25 if(x+1 < n)mp[x*m+y][(x+1)*m+y] = 1; break; 26 case 3: 27 if(y+1 < m) mp[x*m+y][x*m+y+1] = 1; break; 28 } 29 } 30 31 void change(int x, int y) //11个图的连接方式 32 { 33 switch(mpc[x][y]-'A') 34 { 35 case 0: 36 change2(0, x, y); 37 change2(1, x, y); 38 break; 39 case 1: 40 change2(0, x, y); 41 change2(3, x, y); 42 break; 43 case 2: 44 change2(1, x, y); 45 change2(2, x, y); 46 break; 47 case 3: 48 change2(2, x, y); 49 change2(3, x, y); 50 break; 51 case 4: 52 change2(0, x, y); 53 change2(2, x, y); 54 break; 55 case 5: 56 change2(1, x, y); 57 change2(3, x, y); 58 break; 59 case 6: 60 change2(0, x, y); 61 change2(1, x, y); 62 change2(3, x, y); 63 break; 64 case 7: 65 change2(0, x, y); 66 change2(1, x, y); 67 change2(2, x, y); 68 break; 69 case 8: 70 change2(1, x, y); 71 change2(2, x, y); 72 change2(3, x, y); 73 break; 74 case 9: 75 change2(0, x, y); 76 change2(2, x, y); 77 change2(3, x, y); 78 break; 79 case 10: 80 change2(0, x, y); 81 change2(1, x, y); 82 change2(2, x, y); 83 change2(3, x, y); 84 break; 85 } 86 } 87 88 int fd(int x) //寻找父节点 89 { 90 while(x != fm[x]) 91 { 92 x = fm[x]; 93 } 94 return x; 95 } 96 97 void link(int x, int fx) //合并+压缩 98 { 99 int mx; 100 while(x != fm[x]) 101 { 102 mx = x; 103 x = fm[x]; 104 fm[mx] = fx; 105 } 106 fm[x] = fx; 107 } 108 109 void jp(int x, int y) 110 { 111 int fx = fd(x); 112 int fy = fd(y); 113 if(fx != fy) 114 { 115 link(x, fx); 116 link(y, fx); 117 sum++; //统计连接的点的个数 118 } 119 120 } 121 122 int main() 123 { 124 //freopen("test.txt", "r", stdin); 125 while(~scanf("%d%d", &n, &m) && n != -1 && m != -1) 126 { 127 memset(mp, 0, sizeof(mp)); 128 memset(mps, 0, sizeof(mps)); 129 memset(mpc, 0, sizeof(mpc)); 130 for(int i = 0; i < m*n; i++) fm[i] = i; 131 132 for(int i = 0; i < n; i++) 133 { 134 scanf("%s", mpc[i]); 135 for(int j = 0; j < m; j++) 136 { 137 change(i, j); 138 } 139 } 140 for(int i = 0; i < n*m; i++) 141 { 142 for(int j = 0; j < i ; j++) 143 { 144 if(mp[i][j] && mp[j][i]) mps[i][j] = 1; 145 } 146 } 147 148 sum = 0; 149 for(int i = 0; i < n*m; i++) 150 { 151 for(int j = 0; j < i; j++) 152 { 153 if(mps[i][j]) jp(i, j); 154 } 155 } 156 //for(int i = 0; i < m*n; i++) if(fm[i] == i) sum++; 157 158 printf("%d\n", n*m-sum); 159 } 160 return 0; 161 }
对了,这个题dfs也能做,只是我不想再写了……