链接

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\n");
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("\n");
}
} 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\n");
}
}

Codeforces 659F Polycarp and Hay 并查集的更多相关文章

  1. codeforces 659F F. Polycarp and Hay(并查集+bfs)

    题目链接: F. Polycarp and Hay time limit per test 4 seconds memory limit per test 512 megabytes input st ...

  2. Codeforces Round #346 (Div. 2) F. Polycarp and Hay 并查集 bfs

    F. Polycarp and Hay 题目连接: http://www.codeforces.com/contest/659/problem/F Description The farmer Pol ...

  3. Codeforces Round #346 (Div. 2) F. Polycarp and Hay 并查集

    题目链接: 题目 F. Polycarp and Hay time limit per test: 4 seconds memory limit per test: 512 megabytes inp ...

  4. CodeForces 659F Polycarp and Hay

    并查集,$dfs$. 从大的数字往里加,每加一个数字合并一下连通块,判断连通块内数字个数是否够,以及k能不能被当前加入的数字整除.然后$dfs$一下构造答案. #pragma comment(link ...

  5. Codeforces 659F Polycarp and Hay【BFS】

    有毒,自从上次选拔赛(哭哭)一个垃圾bfs写错之后,每次写bfs都要WA几发...好吧,其实也就这一次... 小白说的对,还是代码能力不足... 非常不足... 题目链接: http://codefo ...

  6. codeforces 659F . Polycarp and Hay 搜索

    题目链接 遍历每个点, 如果这个点的值能被k整除并且k/a[i][j]后小于等于n*m, 那么就对这个点进行搜索. 将这个点加入队列, 将周围的所有大于等于这个点的值的点也加入队列. 不断重复, 直到 ...

  7. Codeforces 699D Fix a Tree 并查集

    原题:http://codeforces.com/contest/699/problem/D 题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林.这些从属关系中会有两种环,第一种 ...

  8. Codeforces 731C:Socks(并查集)

    http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问 ...

  9. codeforces 400D Dima and Bacteria 并查集+floyd

    题目链接:http://codeforces.com/problemset/problem/400/D 题目大意: 给定n个集合,m步操作,k个种类的细菌, 第二行给出k个数表示连续的xi个数属于i集 ...

随机推荐

  1. c++面向对象程序设计 谭浩强 第二章答案

    类体内定义成员函数 #include <iostream> using namespace std; class Time { public: void set_time(); void ...

  2. 洛谷P2522 [HAOI2011]Problem b(莫比乌斯反演)

    题目描述 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 输入输出格式 输入格式: 第一行一个整数 ...

  3. 关于Android对话框简单实用方法总结

    要显示一个对话框,首先需要在xx.xml下添加一个Button按钮,并添加一个对应id. 单次点击事件对话框: button.setOnClickListener(new View.OnClickLi ...

  4. thinkphp 5 count()方法在控制器,模板中的使用方法

    thinkphp中关于count()方法的使用: 控制器中:echo count($arr)模板中:{$arr | count}模板中if判断语句中 <if condition="co ...

  5. ZBrush中的布料技巧分享

    今天主要给大家介绍一种在ZBrush®3D图形绘制软件中创建特定类型的布料的技巧,这种方法简单却非常强大. 这个想法源自下面这张图: 我们今天所要讲的技巧可能不是实现复杂的服装设计最有效的方法,但确实 ...

  6. 多进程Socket_Client

    from socket import * #导入套接字模块的所有命令import struct #导入struck模块,用于封装数据流长度# from functools import partial ...

  7. Oracle查询优化之减少统计的数据量

    统计各部门人数很简单,通过部门分组即可,要统计部门以下下级部门的人数也简单,通过递归.要统计所有有下级部门的部门人数(包含下级)页比较简单, 先查询出有下级的部门,在对每个部门进行递归查询,如下: ) ...

  8. node——服务器根据不同请求作出不同响应+响应html文件等文件

    在浏览器中,不同的请求应该作出不同的响应 我们可以从请求req中的url获得请求的内容 然后我们就可以通过判断请求的url来做响应 代码如下: //根据用户的不同请求,服务器做出不同的响应 // // ...

  9. Python笔记25-----------创建二维列表【浅copy】和转置

    一.创建二维列表 1.二维列表创建第二维的时候,如果采用*2这种方式,这是一种浅复制的方式,同时引用到同一个list,如上图的C. 这种形式,不方便修改C[ i ][ j ]的数据,如果改C[ 0 ] ...

  10. Cookie和Session有什么区别

    1. 由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识别具体的用户,这个机制就是Session.   典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状 ...