codeforces 466C Civilization 并查集+dfs
来源:互联网 发布:centos 禁止ping 编辑:程序博客网 时间:2024/05/24 02:38
很容易想到并查集,合并操作的时候在每部分找到一个点使这个点在这棵树上到其他点的最长路径最短,然后将这两个点连线,求一下新的链的长度取最大值就可以了。
设每部分最长路径为 s,到其他点最长路径最短的点的最长路径L为s / 2 (向上取整)
证明:
1.到其他点最长路径为 s / 2 的点一定存在
考虑最长链上的中点m,则m到链较长那边的端点a的路径长为 s/2,假设这条路径不是到m的最长路径,最长路径链接到的点为a1,那么a1->m->b (b为最长链另一个端点)的长度一定大于 a->m->b的长度,与a->m->b为最长链矛盾,因此这条路径一定是到m的最长路径,因此一定存在一个点到其他点最长路径为 s / 2
2.不存在到其他点最长路径小于 s/2 的点
对于树上任意一点k ,由于树的连通性 ,k一定通过 a->m->b上某个点m1与a和b连通,则 k到a的路径长度s1=|k->m1|+|m1->a|,k到b的路径为 s2=|k->m1|+|m1->b| 不妨设 s1>=s2 ,则 |m1->a|>=|m1->b|>= s / 2
即 s1 >= |m1->a| >= s / 2
由1可知 L <= s / 2
由2可知 L >= s / 2
因此 L == s/2
证明完毕
然后一开始用dfs求一下最长链就好
注意dfs要从并查集的根的地方开始
又wa了N次,我真蠢= =
#pragma warning(disable:4996)#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<vector>using namespace std;const int maxn = 300005;int f[maxn],s[maxn],n,m,q;int root(int x) {if (f[x] == -1) return x;return f[x] = root(f[x]);}void merge(int x, int y) {x = root(x);y = root(y);if (x != y) {s[x] = max((s[x] + 1) / 2 + (s[y] + 1) / 2 + 1, s[x]);s[x] = max(s[x], s[y]);f[y] = x;}}vector<int> G[maxn];bool v[maxn];int dfs(int x) {v[x] = 1;int a = 0, son, t;for (int i = 0;i < G[x].size();i++) if (!v[G[x][i]]) {son = G[x][i];t=dfs(son);s[x] = max(s[x], s[son]);s[x] = max(t + a, s[x]);a = max(a, t);}return a + 1;}int main() {memset(f, -1, sizeof(f));cin >> n >> m >> q;int a, b;for (int i = 0;i < m;i++) {scanf("%d%d", &a, &b);G[a].push_back(b);G[b].push_back(a);merge(a, b);}for (int i = 1;i <= n;i++) if(root(i)==i) dfs(i);while (q--) {int md, x, y;scanf("%d", &md);if (md == 1) {scanf("%d", &x);printf("%d\n", s[root(x)]);}else {scanf("%d%d", &x, &y);merge(x, y);}}return 0;}
0 0
- codeforces 466C Civilization 并查集+dfs
- Codeforces 455C Civilization(并查集+dfs)
- Codeforces 455C Civilization(并查集+dfs)
- 【CodeForces】445C Civilization 并查集
- Codeforces 455C Civilization 树的直径+并查集
- 【树的直径+并查集】 codeforces 455C - Civilization
- Codeforces 455C Civilization(并查集+树形dp)
- CodeForces 455C Civilization(并查集+树直径)
- codeforces 455C C. Civilization(树形dp+树的直径+并查集)
- Codeforces 455C —— Civilization(并查集,树上最长链)
- codeforces 455C Civilization 树的最长链+并查集
- Codeforces 455C. Civilization (树的直径+并查集)
- 【打CF,学算法——四星级】CodeForces 455C Civilization (【详解】并查集+树的直径)
- CodeForces445C Civilization 带权并查集
- CF455C Civilization (并查集)
- Codeforces Round #376 (Div. 2) C dfs+并查集
- codeforces round260 div1C&div2E Civilization 并查集+树的直径
- Codeforces 455E Civilization【思维+树的直径+并查集】
- Coding使用的第三方开源库
- 分治法求整数划分
- ftrace 跟踪函数调用
- getopt和getopt_long
- 黑马程序员-----Foundation框架学习之NSArray学习
- codeforces 466C Civilization 并查集+dfs
- 分治法求全排列
- JAVA实现顺时针打印矩阵问题(《剑指offer》)
- 微信-订阅号和服务号的区别
- 30到运维面试题
- 设计模式之java中缓存的基本实现
- keras环境搭建
- Hibernate4在开发当中的一些改变
- 更新Podfile时半天没反应解决方案