您的位置:首页 > 其它

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

2014-08-10 14:32 369 查看
先预处理出每个集合的最长路,就是树的直径,可以两次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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: