zoukankan      html  css  js  c++  java
  • [CF734E] Anton and Tree

    [CF734E] Anton and Tree - 树的直径

    Description

    给定 n 个节点的树,每个点为黑色或白色,一次操作可以使一个相同颜色的连通块变成另一种颜色,求使整棵树变成一种颜色的最少操作数。

    Solution

    将同色连通块缩点后,答案显然等于树的半径

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int a[N], n;
    vector<int> g[N];
    
    namespace segment1
    {
        int fa[N];
    
        int find(int x)
        {
            return x == fa[x] ? x : fa[x] = find(fa[x]);
        }
    
        void merge(int x, int y)
        {
            x = find(x);
            y = find(y);
            fa[x] = y;
        }
    
        void main()
        {
            ios::sync_with_stdio(false);
            cin >> n;
            for (int i = 1; i <= n; i++)
                fa[i] = i;
            for (int i = 1; i <= n; i++)
                cin >> a[i];
            for (int i = 1; i < n; i++)
            {
                int u, v;
                cin >> u >> v;
                g[u].push_back(v);
                g[v].push_back(u);
                if (a[u] == a[v])
                    merge(u, v);
            }
            set<pair<int, int>> s;
            for (int i = 1; i <= n; i++)
            {
                int p = i;
                for (auto j : g[i])
                {
                    int q = j;
                    p = find(i);
                    q = find(j);
                    if (p != q)
                    {
                        if (p > q)
                            swap(p, q);
                        s.insert({p, q});
                    }
                }
            }
            map<int, int> mp;
            for (auto [x, y] : s)
                mp[x]++, mp[y]++;
            int ind = 0;
            for (auto &[x, y] : mp)
                y = ++ind;
            for (int i = 1; i <= n; i++)
                g[i].clear();
            n = ind;
            for (auto [x, y] : s)
            {
                x = mp[x];
                y = mp[y];
                g[x].push_back(y);
                g[y].push_back(x);
            }
        }
    } // namespace segment1
    
    namespace segment2
    {
        int dis[N];
    
        void dfs(int p, int from)
        {
            for (int q : g[p])
                if (q != from)
                {
                    dis[q] = dis[p] + 1;
                    dfs(q, p);
                }
        }
    
        void main()
        {
            dfs(1, 0);
            int mx = 0;
            for (int i = 1; i <= n; i++)
                if (dis[i] > dis[mx])
                    mx = i;
            dis[mx] = 0;
            dfs(mx, 0);
            mx = 0;
            for (int i = 1; i <= n; i++)
                if (dis[i] > dis[mx])
                    mx = i;
            cout << (dis[mx] + 1) / 2 << endl;
        }
    } // namespace segment2
    
    signed main()
    {
        segment1::main();
        segment2::main();
    }
    
  • 相关阅读:
    Python环境变量设置
    Java基础视频笔记(八):多线程编程
    Java基础视频笔记(六):本地文件操作
    设计延迟加载的“单例设计模式”
    Java数组去除重复元素
    博客园真不错,终于发现一个清净之处
    [Architecture Design] 系统边界设计
    [Chatter] 架构设计是做甚么
    [DCF] Devices Communication Foundation Architecture V4
    [WPF] DataTemplate Binding to Interface
  • 原文地址:https://www.cnblogs.com/mollnn/p/14362165.html
Copyright © 2011-2022 走看看