zoukankan      html  css  js  c++  java
  • 将一棵树变成一个环

    A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 unit of cost respectively. The nodes are labeled from 1 to N. Your job is to transform the tree to a cycle(without superfluous edges) using minimal cost.

    A cycle of n nodes is defined as follows: (1)a graph with n nodes and n edges (2)the degree of every node is 2 (3) each node can reach every other node with these N edges.

    InputThe first line contains the number of test cases T( T<=10 ). Following lines are the scenarios of each test case.
    In the first line of each test case, there is a single integer N( 3<=N<=1000000 ) - the number of nodes in the tree. The following N-1 lines describe the N-1 edges of the tree. Each line has a pair of integer U, V ( 1<=U,V<=N ), describing a bidirectional edge (U, V).
    OutputFor each test case, please output one integer representing minimal cost to transform the tree to a cycle.
    Sample Input
    1
    4
    1 2
    2 3
    2 4
    Sample Output
    3
    
            
     
    Hint
    In the sample above, you can disconnect (2,4) and then connect (1, 4) and
    (3, 4), and the total cost is 3.
    

    题意 : 给你一颗树,要求将此树变成一个环,并且要求每个点的度为2,删去或增加一条边的花费都是1,求最小的花费。

    思路分析:思维题,对于树上的点如果其不是根节点并且具有3个分支,则其一定要去掉一个,保留两个,然后其在返回父节点的时候它是不给父节点在提供任何分支的,否则会提供一个分支。

    代码示例:

    const int maxn = 1e6+5;
    
    int n;
    vector<int>ve[maxn];
    int ans;
    
    int dfs(int x, int fa){
        int sum = 0;
        
        for(int i = 0; i < ve[x].size(); i++){
            int to = ve[x][i];
            if (to == fa) continue; 
            sum += dfs(to, x);
        }
        if (x != 1 && sum >= 2){
            ans += sum-1;
            return 0;        
        }
        else if (x == 1 && sum > 2){
            ans += sum-2;
        }
        return 1; 
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int t;
        int x, y;
        
        cin >> t;
        while(t--){
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) ve[i].clear();
            for(int i = 1; i < n; i++){
                scanf("%d%d", &x, &y);
                ve[x].push_back(y);
                ve[y].push_back(x);        
            }  
            ans = 0;
            dfs(1, 0);
            printf("%d
    ", ans*2+1);
        }
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    libuv 中文编程指南(一)序言
    一些鲜为人知却非常实用的数据结构
    libuv 中文编程指南(二)libuv 基础
    Zookeeper 的 Lua 绑定(二)
    高度怀疑
    不能没有你
    第一次看流星雨记
    调侃下蓝网队 我还是比较极端的 不要好 那就要坏吧
    摇滚校园
    守法公民
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9185828.html
Copyright © 2011-2022 走看看