• Codeforces 659F Polycarp and Hay 并查集


    链接

    Codeforces 659F Polycarp and Hay

    题意

    一个矩阵,减小一些数字的大小使得构成一个连通块的和恰好等于k,要求连通块中至少保持一个不变

    思路

    将数值从小到大排序,按顺序把与其相邻的加到并查集中。记录当前并查集中的个数,如果当前值能被K整除且总和超过了K,那么就可以以该点为中心输出了。

    代码

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <cmath>
    #include <cstring>
    #include <string>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    
    using namespace std;
    
    struct node{
    	int x, y;
    	LL val;
    };
    node b[1000005];
    int father[1000005];
    int a[1005][1005];
    bool vis[1005][1005];
    LL num[1000005];
    const int step[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
    int n, m;
    int get_father(int x){
    	if (father[x] == x) return x;
    	return father[x] = get_father(father[x]);
    }
    bool compare(node a, node b){
    	return a.val > b.val;
    }
    
    void bfs(node u, LL k){
    	queue<node> Q;
    	int val = u.val;
    	u.val = 1;
    	Q.push(u);
    	memset(vis, 0, sizeof(vis));
    	vis[u.x][u.y] = true;
    	int tag = k / (LL)val;
    	int cnt = 1;
    	bool flag = false;
    	while (!Q.empty()){
    		u = Q.front(); Q.pop();
    		for (int i = 0; i < 4; ++i){
    			int x = u.x + step[i][0];
    			int y = u.y + step[i][1];
    			if (x < 1 || x > n || y < 1 || y > m || a[x][y] < val || vis[x][y] || cnt >= tag) continue;
    			node t = u;
    			t.x = x, t.y = y;
    			++cnt;
    			vis[x][y] = true;
    			if (cnt == tag){
    				flag = true;
    				break;
    			}
    			Q.push(t);
    		}
    		if (flag) break;
    	}
    	printf("YES
    ");
    	for (int i = 1; i <= n; ++i){
    		for (int j = 1; j <= m; ++j){
    			if (vis[i][j]){
    				printf("%d ", val);
    			}
    			else{
    				printf("0 ");
    			}
    		}
    		printf("
    ");
    	}
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
    	LL k;
    	while (~scanf("%d%d%I64d", &n, &m, &k)){
    		int t = 0;
    		for (int i = 1; i <= n; ++i){
    			for (int j = 1; j <= m; ++j){
    				scanf("%d", &a[i][j]);
    				b[t].y = j;
    				b[t].val = a[i][j];
    				++t;
    			}
    		}
    		for (int i = 0; i < n * m; ++i){
    			father[i] = i;
    			num[i] = 1;
    		}
    		sort(b, b + n * m, compare);
    		for (int i = 0; i < n * m; ++i){
    			int x, y;
    			int p = (b[i].x - 1) * m + b[i].y;
    			for (int j = 0; j < 4; ++j){
    				x = b[i].x + step[j][0];
    				y = b[i].y + step[j][1];
    				if (x < 1 || x > n || y < 1 || y > m || a[x][y] < b[i].val) continue;
    				int q = (x - 1) * m + y;
    				int xf = get_father(p), yf = get_father(q);
    				if (xf != yf){
    					father[xf] = yf;
    					num[yf] += num[xf];
    					num[xf] = 0;
    				}
    			}
    			int yf = get_father(p);
    			if (k % b[i].val == 0 && num[yf] * b[i].val >= k){
    				bfs(b[i], k);
    				return 0;
    			}
    		}
    		printf("NO
    ");
    	}
    }
    
  • 相关阅读:
    异步与回调的设计哲学
    CTF之PHP黑魔法总结
    图片隐写分离
    phpMyadmin各版本漏洞
    python 多线程
    order by name 注入
    Python lambda
    Python os.popen() 方法
    你和大牛差了啥
    Error: failure: repodata/repomd.xml from fedora: [Errno 256] No more mirrors to try.
  • 原文地址:https://www.cnblogs.com/macinchang/p/5556500.html
Copyright © 2020-2023  润新知