Codeforces 455C Civilization(并查集+dfs)

来源:互联网 发布:甘肃扶贫大数据平台 编辑:程序博客网 时间:2024/05/18 18:53

题目链接:Codeforces 455C Civilization

题目大意:给定N,M和Q,N表示有N个城市,M条已经修好的路,修好的路是不能改变的,然后是Q次操作,操作分为两种,一种是查询城市x所在的联通集合中,最长的路为多长。二是连接两个联通集合,采用联通之后最长路最短的方案。

解题思路:因为一开时的图是不可以改变的,所以一开始用dfs处理出各个联通集合,并且记录住最大值,然后就是Q次操作,用并查集维护,注意因为联通的时候要采用最长路径最短的方案,所以s的转移方程变为s = max(s, (s+1)/2 + (s0+1)/2 + 1)

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 3 * 1e5 + 5;int N, M, Q, f[maxn], s[maxn];int root, ans, rec;vector<int> g[maxn];int getfar(int x) {    return f[x] == x ? x : f[x] = getfar(f[x]);}void link (int u, int v) {    int x = getfar(u);    int y = getfar(v);    if (x == y)        return;    if (s[x] < s[y])        swap(s[x], s[y]);    f[y] = x;    s[x] = max(s[x], (s[x] + 1) / 2 + (s[y] + 1) / 2 + 1);}void dfs (int u, int p, int d) {    f[u] = root;    if (d > ans) {        ans = d;        rec = u;    }    for (int i = 0; i < g[u].size(); i++) {        if (g[u][i] != p)            dfs(g[u][i], u, d+1);    }}int main () {    int type, u, v;    scanf("%d%d%d", &N, &M, &Q);    for (int i = 1; i <= N; i++) {        f[i] = i;        g[i].clear();    }    for (int i = 0; i < M; i++) {        scanf("%d%d", &u, &v);        g[u].push_back(v);        g[v].push_back(u);    }    for (int i = 1; i <= N; i++) {        if (f[i] == i) {            root = rec = i;            ans = -1;            dfs(i, 0, 0);            ans = -1;            dfs(rec, 0, 0);            s[i] = ans;        }    }    for (int i = 0; i < Q; i++) {        scanf("%d", &type);        if (type == 1) {            scanf("%d", &u);            v = getfar(u);            printf("%d\n", s[v]);        } else {            scanf("%d%d", &u, &v);            link(u, v);        }    }    return 0;}
2 0
原创粉丝点击