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也能做,只是我不想再写了……

posted @ 2015-05-03 13:50  mypride  阅读(177)  评论(0编辑  收藏  举报