• 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;
    }
    
  • 相关阅读:
    VueRouter认识
    vuejs组件
    vue初级使用
    Apache Shiro初认识
    解决表单提交的数据丢失问题
    浅析SpringDataJpa继承结构
    HTTP Status 500
    Eclipse快捷键
    JavaScript(JS)的简单使用
    mysql 函数 GROUP_CONCAT 单元格中最长字符串和excel导出问题
  • 原文地址:https://www.cnblogs.com/jiupinzhimaguan/p/13806447.html
Copyright © 2020-2023  润新知