zoukankan      html  css  js  c++  java
  • 【27.91%】【codeforces 734E】Anton and Tree

    time limit per test3 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Anton is growing a tree in his garden. In case you forgot, the tree is a connected acyclic undirected graph.

    There are n vertices in the tree, each of them is painted black or white. Anton doesn’t like multicolored trees, so he wants to change the tree such that all vertices have the same color (black or white).

    To change the colors Anton can use only operations of one type. We denote it as paint(v), where v is some vertex of the tree. This operation changes the color of all vertices u such that all vertices on the shortest path from v to u have the same color (including v and u). For example, consider the tree

    and apply operation paint(3) to get the following:

    Anton is interested in the minimum number of operation he needs to perform in order to make the colors of all vertices equal.

    Input
    The first line of the input contains a single integer n (1 ≤ n ≤ 200 000) — the number of vertices in the tree.

    The second line contains n integers colori (0 ≤ colori ≤ 1) — colors of the vertices. colori = 0 means that the i-th vertex is initially painted white, while colori = 1 means it’s initially painted black.

    Then follow n - 1 line, each of them contains a pair of integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi) — indices of vertices connected by the corresponding edge. It’s guaranteed that all pairs (ui, vi) are distinct, i.e. there are no multiple edges.

    Output
    Print one integer — the minimum number of operations Anton has to apply in order to make all vertices of the tree black or all vertices of the tree white.

    Examples
    input
    11
    0 0 0 1 1 0 1 0 0 1 1
    1 2
    1 3
    2 4
    2 5
    5 6
    5 7
    3 8
    3 9
    3 10
    9 11
    output
    2
    input
    4
    0 0 0 0
    1 2
    2 3
    3 4
    output
    0
    Note
    In the first sample, the tree is the same as on the picture. If we first apply operation paint(3) and then apply paint(6), the tree will become completely black, so the answer is 2.

    In the second sample, the tree is already white, so there is no need to apply any operations and the answer is 0.

    【题目链接】:http://codeforces.com/contest/734/problem/E

    【题解】

    贪心。
    那些相连的点,且颜色相同的。把它们缩成一个点.
    最后整张图还是一棵树.(每相邻的两个节点颜色都不一样,一个节点代表了一个团块)
    然后找到树的直径。
    在直径那条路径的终点处一直进行操作就可以了(即一直painting(直径的终点));
    这样操作直径/2次,最后整棵树的颜色肯定都是一样的了。
    (在其他位置弄,想来也没有直径/2这个位置优吧..直觉题。。)

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int MAXN = 2e5+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n;
    int a[MAXN],f[MAXN],s,t,dis[MAXN],ma = 0;
    vector <pii> edge;
    vector <int> G[MAXN];
    
    int ff(int x)
    {
        if (f[x] == x)
            return x;
        else
            f[x] = ff(f[x]);
        return f[x];
    }
    
    void dfs(int x,int fa)
    {
        if (dis[x] > ma)
        {
            ma = dis[x];
            t = x;
        }
        for (auto y:G[x])
        {
            if (y!=fa)
            {
                dis[y] = dis[x] + 1;
                dfs(y,x);
            }
        }
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(n);
        rep1(i,1,n)
            rei(a[i]),f[i] = i;
        rep1(i,0,n-2)
            {
                int x,y;
                rei(x);rei(y);
                int r1 = ff(x),r2 = ff(y);
                if (r1 != r2 && a[r1]==a[r2])
                    f[r1] = r2;
                edge.pb(mp(x,y));
            }
        rep1(i,0,n-2)
            {
                int x,y;
                x = edge[i].fi,y = edge[i].se;
                int r1 = ff(x),r2 = ff(y);
                if (r1!=r2)
                    G[r1].pb(r2),G[r2].pb(r1);
            }
        ma = 0;
        int s = ff(1);
        dis[s] = 1;
        dfs(s,-1);
        memset(dis,0,sizeof dis);
        ma = 0;
        s = t;
        dis[s] = 1;
        dfs(s,-1);
        cout << ma/2;
        return 0;
    }
  • 相关阅读:
    Appium学习笔记(一)--安装与配置
    google软件测试之道--读后笔记
    Web测试中常见分享问题
    730工作总结
    Java源码分析系列
    LeetCode 21 -- Merge Two Sorted Lists
    LeetCode 20 -- Valid Parentheses
    LeetCode 15 -- 3Sum
    LeetCode 11 -- Container With Most Water
    ASP.NET Core MVC中Hangfire及EF Core的简单使用
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626806.html
Copyright © 2011-2022 走看看