【树的直径+并查集】 codeforces 455C - Civilization

来源:互联网 发布:java dwg转jpg 编辑:程序博客网 时间:2024/05/05 05:29

先预处理出每个集合的最长路,就是树的直径,可以两次BFS找。。然后合并集合更新最长路就是在dep[a],dep[b],(dep[a]+1)/2+(dep[b]+1)/2+1三者取最大。。

#include <iostream>  #include <queue>  #include <stack>  #include <map>  #include <set>  #include <bitset>  #include <cstdio>  #include <algorithm>  #include <cstring>  #include <climits>  #include <cstdlib>#include <cmath>#include <time.h>#define maxn 300005#define maxm 100005#define eps 1e-10#define mod 3#define INF 1e9#define lowbit(x) (x&(-x))  #define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid  #define rson o<<1 | 1, mid+1, R  typedef long long LL;//typedef int LL;using namespace std;int n, m;int f[maxn], dep[maxn];vector<int> vec[maxn];vector<int> g[maxn];set<int> s[maxn];queue<int> q;int vis[maxn];int dis[maxn];int find(int x){return x == f[x] ? x : f[x] = find(f[x]);}void debug(void){for(int i = 1; i <= n; i++)printf("AA  %d  BB\n", dep[i]);}int bfs(int u){int d = g[f[u]].size(), mx;for(int i = 0; i < d; i++) dis[g[f[u]][i]] = INF;q.push(u), dis[u] = 0, mx = u;while(!q.empty()) {int x = q.front();q.pop();int d = vec[x].size();for(int i = 0; i < d; i++) {if(dis[vec[x][i]] > dis[x] + 1) {dis[vec[x][i]] = dis[x] + 1;q.push(vec[x][i]);if(dis[vec[x][i]] > dis[mx])mx = vec[x][i];}}}return mx;}void init(void){int q, u, v, aa, bb;scanf("%d%d%d", &n, &m, &q);for(int i = 0; i <= n; i++) f[i] = i;while(m--) {scanf("%d%d", &u, &v);vec[u].push_back(v);vec[v].push_back(u);aa = find(u);bb = find(v);if(aa == bb) continue;else if(aa < bb) f[bb] = aa;else f[aa] = bb;}m = q;for(int i = 1; i <= n; i++) find(i);for(int i = 1; i <= n; i++) {s[f[i]].insert(i);g[f[i]].push_back(i);}for(int i = 1; i <= n; i++) {if(f[i] == i) {int tmp = bfs(i);tmp = bfs(tmp);dep[i] = dis[tmp];}}}void work(void){int k, a, b, aa, bb;while(m--) {scanf("%d", &k);if(k == 1) {scanf("%d", &a);aa = find(a);printf("%d\n", dep[aa]);}else {scanf("%d%d", &a, &b);aa = find(a);bb = find(b);if(aa == bb) continue;int tmp = (dep[aa] + 1)/2 + (dep[bb] + 1)/2 + 1;tmp = max(tmp, max(dep[aa], dep[bb]));if(aa > bb) f[aa] = bb, dep[bb] = tmp;else f[bb] = aa, dep[aa] = tmp;}}}int main(void){init();work();return 0;}


0 0
原创粉丝点击