zoukankan      html  css  js  c++  java
  • Tree split (cut)

    Description


    There is an unrooted tree with (n) nodes, each node is numbered (1 sim n). Now it is required to delete one of the nodes so that the number of nodes in each subtree part that is divided does not exceed (n/2).

    Format


    Input

    The first line is a positive integer (t(≤5)), indicating the number of test data groups; in each group of data, the first line is a positive integer (n(≤10^5)), and the next (n-1) lines have two positive integers (x) and (y) ((x, y≤n)), respectively represent the two node numbers connecting the edges.

    Output

    For each group of data, output the number of the split point. If there are more than one node, output in the order from smallest to largest; if not, output "None".

    Sample


    Input

    2
    10
    1 2
    2 3
    3 4
    4 5
    6 7
    7 8
    8 9
    9 10
    3 8
    5
    1 5
    5 2
    3 4
    4 1
    

    Output

    3 8
    1
    

    Sample Explanation

    The tree of sample 1 is shown in the figure below, and nodes 3 and 8 meet the conditions:
    pic

    Sample Code


    #include <cstdio>
    #include <cstring>
    const int N=100010;
    struct Edge{
        int v, next;
    }edge[2*N]; 
    struct Head{
        int deg, mmax, first;
    }head[N];//deg记录以当前点为根的子树总结点数(度),mmax记录其子树中度的最大值 
    int now, n;
    bool vis[N];
    
    void in(int &s){
    	char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	for (s=0; c>='0' && c<='9'; c=getchar())
    		s=s*10+c-'0';
    }
    inline int mx(int a, int b){
    	return a>b ? a : b;
    }
    void ins(int x, int y){
    	now++; edge[now].v=y; 
    	edge[now].next=head[x].first; head[x].first=now;
    }//头插法建立链式前向星 
    
    void dfs(int r){
        vis[r]=1;
        int deg=1, tp=0;
        for (int k=head[r].first; k; k=edge[k].next){
            int v=edge[k].v;
            if (!vis[v]){
                dfs(v);
                if (head[v].deg > tp) 
                    tp=head[v].deg;
                deg+=head[v].deg;
            }
        }
        head[r].deg=deg;//记录当前子树的总结点数(度) 
        head[r].mmax=mx(tp, n-deg);//记录所有子树中的最大度 
    }
    int main(){
        freopen("cut.in", "r", stdin);
        freopen("cut.out", "w", stdout);
        int t;
        scanf("%d", &t);
        while (t--){
    		scanf("%d", &n);
            memset(vis, 0, sizeof(vis));
            memset(head, 0, sizeof(head));
    		int x, y;
            now=0;
            for (int i=1; i<n; i++){
                in(x), in(y);//scanf("%d %d", &x, &y); 
                ins(x, y); ins(y, x);
            }
            dfs(1); 
    		bool ok=false;
            for (int i=1; i<=n; i++)
                //if (n-head[i].deg <= n/2 && head[i].mmax <= n/2){
    			if (head[i].mmax <= n/2){
                    printf("%d ", i); ok=true;
                }//n-head[i].deg表示除去当前子树外其他所有结点总数(恰好构成另一个方向的子树) 
            if (!ok) printf("None");
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    window 操作
    idea使用
    安装zookeeper
    resource和autowired
    python浅见 (Python 3000)
    Tomcat服务器
    servlet
    事件是一种委托吗?什么是委托?什么是事件?
    int值类型的ToString()方法是否装箱
    抽象类,虚方法与普通类的区别
  • 原文地址:https://www.cnblogs.com/jiupinzhimaguan/p/13806447.html
Copyright © 2011-2022 走看看