zoukankan      html  css  js  c++  java
  • Codeforces Round #670 (Div. 2)(树的重心,dfs求子树大小)

    地址:http://codeforces.com/contest/1406/problem/C

    题意:

    给出n个点,n-1条边。

    通过删除一条边,增加一条边,使得重心唯一

    重心:树的某个节点,当去掉该节点后,树的各个连通分量中,节点数最多的连通分量其节点数达到最小值。

    解析:

    关于重心的一个性质:

    一棵树最多两个重心,若两个,则相邻。

    那么,如果一个点x为重心,其子树点的数目一定为n/2,那么与他相邻的那个点y,其含有的点数目要么为n/2,要么为n/2+1

    不管是剩n/2还是n/2+1,只要某个子树达到了n/2大小,都进行一次操作:

    找出y的其中一个子节点,断掉,与x连上。

    此时不管y是否为重心,都可以保证重心唯一。

    而如果没有出现大小为n/2的子树,那么重心一定唯一,此时删加同一条边即可。

    #include <bits/stdc++.h>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5+10;
    vector<int>g[maxn];
    int si[maxn];
    int n;
    int ok  = 0 ;
    int x,y;
    int dfs(int v,int f)
    {
        si[v]=1;
        for(int i=0;i<g[v].size();i++)
        {
            if(f!=g[v][i])
            {
                dfs(g[v][i],v);
                si[v]+=si[g[v][i]];
            }
        }
        if(si[v]==n/2)
        {
            x=v;
            y=f;
            ok=1;
        }
    }
    int main(){
        int t;
        cin >> t;
        while(t--) {
            ok=0;
            scanf("%d",&n);
            for(int i=0;i<maxn;i++)
            {
                g[i].clear();
                si[i]=0;
            }
            int a,b;
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&a,&b);
                g[a].push_back(b);
                g[b].push_back(a);
            }
            dfs(1,0);
            if(!ok)
            {
                cout<<a<<" "<<b<<endl;
                cout<<a<<" "<<b<<endl;
            }
            else
            {
                for(int i=0;i<g[y].size();i++)
                {
                    if(g[y][i]!=x)
                    {
                        cout<<g[y][i]<<" "<<y<<endl;
                        cout<<g[y][i]<<" "<<x<<endl;
                        break;
                    }
                }
            }
          }
    }
  • 相关阅读:
    补:冲刺Day1
    需求规格说明书2.0
    补:冲刺Day2
    冲刺Day3
    Base64上传图片
    C#怎样通过url调用接口
    js键盘控制DIV移动
    利用MVC的过滤器实现url的参数加密和解密
    在.net MVC中异步上传图片或者文件
    mvc url路由参数的加密和解密
  • 原文地址:https://www.cnblogs.com/liyexin/p/13681521.html
Copyright © 2011-2022 走看看