zoukankan      html  css  js  c++  java
  • 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*m-sum);
    159     }
    160     return 0;
    161 }

     对了,这个题dfs也能做,只是我不想再写了……

  • 相关阅读:
    关于trunk、access以及hybrid的一些简单知识
    EasyUI 创建对话框
    EasyUI Window和Layout
    EasyUI 异步Tree
    EasyUI 创建Tree
    EasyUI Tree添加节点
    EasyUI Ajax 表单
    EasyUI Tree checkbox node
    EasyUI 表单 tree
    EasyUI DataGrid合并单元
  • 原文地址:https://www.cnblogs.com/mypride/p/4473939.html
Copyright © 2011-2022 走看看