codeforces723 D. Lakes in Berland(并查集)

题目链接:codeforces723 D. Lakes in Berland

参考博客:http://www.cnblogs.com/Geek-xiyang/p/5930245.html

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<algorithm>
  5 #define CLR(a,b) memset((a),(b),sizeof((a)))
  6 using namespace std;
  7 const int N = 52;
  8 const int M = 2800;
  9 int n, m, k;
 10 char ch[N][N];
 11 int val[N][N];
 12 int fa[M], num[M];
 13 bool vis[M];
 14 int dx[] = {0,0,1,-1};
 15 int dy[] = {1,-1,0,0};
 16 void init(){
 17     CLR(ch,'.');
 18     int cnt = 0;
 19     for(int i = 0; i <= n+1; ++i)
 20         for(int j = 0; j <= m+1; ++j)
 21             val[i][j] = ++cnt;
 22     for(int i = 1; i <= cnt; ++i){
 23         fa[i] = i;
 24         num[i] = 1;
 25     }
 26 }
 27 int fin(int x){
 28     if(x != fa[x])
 29         fa[x] = fin(fa[x]);
 30     return fa[x];
 31 }
 32 void uni(int x, int y){
 33     if((x = fin(x)) == (y = fin(y))) return;
 34     else {
 35         fa[x] = y;
 36         num[y] += num[x];
 37     }
 38 }
 39 void make(int i, int j){
 40     for(int k = 0; k < 4; ++k){
 41         if(ch[dx[k]+i][dy[k]+j] == '.')
 42             uni(val[i][j], val[dx[k]+i][dy[k]+j]);
 43     }
 44 }
 45 bool cmp(int x, int y){
 46     return num[x] < num[y];
 47 }
 48 vector<int>v;
 49 int main(){
 50     int i, j, kk, rt, t;
 51     scanf("%d%d%d", &n, &m, &k);
 52     init();
 53     for(i = 0; i <= n+1; ++i){
 54         uni(val[0][0], val[i][0]);
 55         uni(val[0][0], val[i][m+1]);
 56     }
 57     for(i = 0; i <= m+1; ++i){
 58         uni(val[0][0], val[0][i]);
 59         uni(val[0][0], val[n+1][i]);
 60     }
 61     for(i = 1; i <= n; ++i){
 62         scanf("%s", ch[i]+1);
 63         ch[i][m+1] = '.';//第二遍改时把这句漏了继续WA
 64     }
 65     for(i = 1; i <= n; ++i)
 66         for(j = 1 ; j <= m; ++j)
 67             if(ch[i][j] == '.')
 68                 make(i, j);
 69     for(i = 1; i <= n; ++i){
 70         for(j = 1; j <= m; ++j){
 71             rt = fin(val[i][j]);
 72             if(ch[i][j] == '.' && fin(val[0][0]) != rt){
 73                 if(vis[rt]) continue;
 74                 else  vis[rt] = true;
 75                 v.push_back(rt);
 76             }
 77         }
 78     }
 79     sort(v.begin(), v.end(), cmp);
 80     int len = v.size();
 81     t = len;
 82     int ans = 0;
 83     if(t > k){
 84         for(i = 0; i < len; ++i){
 85             rt = fin(v[i]);
 86             if(vis[rt]){
 87                 vis[rt] = false;
 88                 t--;
 89                 for(j = 1; j <= n; ++j)
 90                     for(kk = 1; kk <= m; ++kk)//我第一遍把这里写成k导致WA死
 91                         if(fin(val[j][kk]) == rt) {ch[j][kk] = '*'; ans++;}
 92             }
 93             if(t == k) break;
 94         }
 95     }
 96     printf("%d\n", ans);
 97     for(i = 1; i <= n; ++i){
 98         for(j = 1; j <= m; ++j)
 99             printf("%c", ch[i][j]);
100         puts("");
101     }
102     return 0;
103 }
View Code

 

转载于:https://www.cnblogs.com/GraceSkyer/p/5933738.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值