PAT A 1021. Deepest Root

来源:互联网 发布:淘宝企业店铺名称 编辑:程序博客网 时间:2024/06/03 22:45

1021. Deepest Root (25)

P 判断连通:并查集.找最长的根,两步DFS.第一个DFS从一个点出发,找到里这个点最远的点集合,这个在ANS里面.第二部从ANS里任意找个点,再DFS.又找到最远的点集.两个点集的并集,就是ANS.不要问我为什么,我也不知道.

#include <bits/stdc++.h>using namespace std;struct UnionFind{    vector<int> id, sz;    int n, cnt;    UnionFind(int n) : n(n)    {        id.resize(n);        sz.resize(n);        for (int i = 0; i < n; i++) {            id[i] = i;            sz[i] = 1;        }        cnt = n;    }    int fd(int x)    {        if (x == id[x]) return x;        return id[x] = fd(id[x]);    }    void unite(int x, int y)    {        x = fd(x), y = fd(y);        if (x == y) return;        if (sz[x] < sz[y]) swap(x, y);        id[y] = x;        sz[x] += sz[y];        cnt--;    }};vector< vector<int> > g;set<int> ans;vector<int> ans2;int maxh, maxh2;void dfs(int u, int f, int h){    if (h > maxh) {        maxh = h;        ans.clear();        ans.insert(u);    } else if (h == maxh) {        ans.insert(u);    }    for (int v : g[u]) {        if (v == f) continue;        dfs(v, u, h + 1);    }}void dfs2(int u, int f, int h){    if (h > maxh2) {        maxh2 = h;        ans2.clear();        ans2.push_back(u);    } else if (h == maxh2)    {        ans2.push_back(u);    }    for (int v : g[u]) {        if (v == f) continue;        dfs2(v, u, h + 1);    }}int main(){    //freopen("in", "r", stdin);    int N;    scanf("%d", &N);    UnionFind uf(N);    g.resize(N);    maxh = 0;    for (int i = 0; i < N - 1; i++) {        int u, v;        scanf("%d%d", &u, &v);        u--, v--;        g[u].push_back(v);        g[v].push_back(u);        uf.unite(u, v);    }    if (uf.cnt > 1) {        printf("Error: %d components\n", uf.cnt);        return 0;    }    dfs(0, -1, 0);    maxh2 = 0;    dfs2(*ans.begin(), -1, 0);    for (int e : ans2) {        ans.insert(e);    }    for (int e : ans) {        cout << e + 1 << endl;    }}
0 0