zoukankan      html  css  js  c++  java
  • Codeforces Round #260 (Div. 1)——Civilization

    题目链接

    • 题意:
      n个点,m条边的森林。q次操作。

      每次操作:1、询问x所在树的直径 2、合并x和y所在的树,使得合并后的直径最小
      (1 ≤ n ≤ 3·1050 ≤ m < n1 ≤ q ≤ 3·105)

    • 分析:
      没有读到图是森林。。

      。做的好纠结
      最開始将每一个树都求一下直径,之后使用并查集处理。每次合并直径:至少是两个树的直径,或者将两个直径的最中间的部分连接求直径

    const int MAXN = 310000;
    
    int rt[MAXN], ans[MAXN];
    VI G[MAXN];
    bool vis[MAXN];
    
    void init(int n)
    {
        REP(i, n)
        {
            vis[i] = false;
            ans[i] = 0;
            G[i].clear();
            rt[i] = i;
        }
    }
    
    int find(int n)
    {
        return n == rt[n] ? n : rt[n] = find(rt[n]);
    }
    
    void merge(int a, int b)
    {
        int fa = find(a), fb = find(b);
        if (fa != fb)
        {
            rt[fa] = fb;
            ans[fb] = max(ans[fb], (ans[fb] + 1) / 2 + (ans[fa] + 1) / 2 + 1);
            ans[fb] = max(ans[fa], ans[fb]);
        }
    }
    
    int Max, id;
    void dfs(int u, int fa, int dep)
    {
        vis[u] = true;
        REP(i, G[u].size())
        {
            int v = G[u][i];
            if (v != fa)
                dfs(v, u, dep + 1);
        }
        if (dep > Max)
        {
            Max = dep;
            id = u;
        }
    }
    
    int main()
    {
        int n, m, q;
        while (~RIII(n, m, q))
        {
            init(n + 1);
            REP(i, m)
            {
                int a, b;
                RII(a, b);
                G[a].push_back(b);
                G[b].push_back(a);
                int fa = find(a), fb = find(b);
                rt[fa] = fb;
            }
            FE(i, 1, n)
            {
                if (!vis[i])
                {
                    Max = -1;
                    dfs(i, -1, 0);
                    Max = -1;
                    dfs(id, -1, 0);
                    ans[find(i)] = Max;
                }
            }
            REP(i, q)
            {
                int op;
                RI(op);
                if (op == 2)
                {
                    int a, b;
                    RII(a, b);
                    merge(a, b);
                }
                else
                {
                    int a;
                    RI(a);
                    WI(ans[find(a)]);
                }
            }
        }
        return 0;
    }


  • 相关阅读:
    jquery attribute!=value选择器 语法
    jquery attribute=value选择器 语法
    jquery attribute选择器 语法
    jquery visible 选择器 语法
    jquery empty选择器 语法
    jquery contains选择器 语法
    jquery animated选择器 语法
    jquery header选择器 语法
    jquery lt选择器 语法
    jquery gt选择器 语法
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7054726.html
Copyright © 2011-2022 走看看