zoukankan      html  css  js  c++  java
  • Codeforces 1092E Minimal Diameter Forest

    Minimal Diameter Forest

    首先我们找出每个连通块中的特殊点, 特殊点的定义是到各种个连通块中距离的最大值最小的点, 

    每个连通块肯定通过特殊点连到其他连通块, 我们把有最大值的特殊点当作根, 然后其他点直接接在这个点中, 形成菊花图。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 1000 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    int n, m, cnt, mx, DIA, belong[N], mn[N], who[N], id[N], dia[N];
    vector<int> G[N];
    
    void dfs(int u) {
        belong[u] = cnt;
        for(auto& v : G[u])
            if(!belong[v]) dfs(v);
    }
    void dfs2(int u, int fa, int depth) {
        mx = max(mx, depth);
        for(auto& v : G[u])
            if(v != fa) dfs2(v, u, depth + 1);
    }
    
    bool cmp(const int& x, const int& y) {
        return mn[x] > mn[y];
    }
    
    int main() {
        memset(mn, inf, sizeof(mn));
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            int u, v; scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        for(int i = 1; i <= n; i++) {
            if(!belong[i]) ++cnt, dfs(i);
        }
        for(int i = 1; i <= n; i++) {
            mx = 0;
            dfs2(i, 0, 0);
            if(mx < mn[belong[i]]) {
                mn[belong[i]] = mx;
                who[belong[i]] = i;
            }
            dia[belong[i]] = max(dia[belong[i]], mx);
        }
        for(int i = 1; i <= cnt; i++) {
            id[i] = i;
            DIA = max(DIA, dia[i]);
        }
        sort(id + 1, id + 1 + cnt, cmp);
        if(cnt >= 2) DIA = max(DIA, mn[id[1]] + mn[id[2]] + 1);
        if(cnt >= 3) DIA = max(DIA, mn[id[2]] + mn[id[3]] + 2);
        printf("%d
    ", DIA);
        for(int i = 2; i <= cnt; i++) printf("%d %d
    ", who[id[1]], who[id[i]]);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    学习进度表
    第八次日志
    第七次日志
    第六次日志
    第五次日志
    第四次日志
    第一次日志
    第三次日志
    第二次日志
    学习进度表
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10492626.html
Copyright © 2011-2022 走看看