zoukankan      html  css  js  c++  java
  • HDU 4714 Tree2cycle 找规律

    假设最少删除的边的个数为cost,显然,最终答案即为cost+cost+1 (因为删除一条边,就会增加一个链,所以删除cost条边后,就会有cost+1条链,将这cost+1条链连接起来的代价为cost+1, 删除cost条边的代价为cost,所以总代价为cost+cost+1)

    求最少删除的边数:

    首先我们定义一棵子树中的链不能以该子树的根为端点,以下提到的所有链均必须满足这个条件。

    设一棵以节点i为根的子树中,叶子节点的个数为duan,并设i的父亲为fa。

    那么,这棵子树至少会分割成duan-1条链(以其中两个叶子为端形成一条链,剩下的一个叶子对应一条链)。

    DFS,对于某棵以节点i为根的子树,如果子树中叶子节点个数<=1,那么在这棵子树内无法分割成完整的一条链(分割成完整的链至少需要两个叶子),相当于对fa而言,节点i依然是一个叶子。

    如果子树中有>=2个叶子,那么这棵子树内可以分割成完整的duan-1条链,相当于对fa而言,删掉节点i及以i为根的子树。

    PS1.对于没有fa的节点特殊判断一下。

    PS2.手动扩栈

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int MAXN = 1000100;
    
    struct node
    {
        int v;
        int next;
    };
    
    int n;
    node D[MAXN<<1];
    int head[MAXN];
    int cost, EdgeN;
    
    void AddEdge( int u, int v )
    {
        D[EdgeN].v = v;
        D[EdgeN].next = head[u];
        head[u] = EdgeN++;
        return;
    }
    
    int DFS( int cur, int fa )
    {
        int duan = 0;
        for ( int i = head[cur]; i != -1; i = D[i].next )
        {
            if ( D[i].v != fa )
                duan += DFS( D[i].v, cur );
        }
        if ( duan < 2 ) return 1;
        else
        {
            if ( cur == 1 ) cost += duan - 2;   //如果是根节点
            else cost += duan - 1;
            return 0;
        }
    }
    
    int main()
    {
        int T;
        scanf( "%d", &T );
        while ( T-- )
        {
            scanf( "%d", &n );
            memset( head, -1, sizeof(int)*(n+1) );
            EdgeN = 0;
            for ( int i = 1; i < n; ++i )
            {
                int u, v;
                scanf( "%d%d", &u, &v );
                AddEdge( u, v );
                AddEdge( v, u );
            }
    
            cost = 0;
            DFS( 1, -1 );
            int ans = cost + 1 + cost;
            printf("%d
    ", ans );
        }
        return 0;
    }
  • 相关阅读:
    [PHP]算法-归并排序的PHP实现
    [PHP] 数据结构-二叉树的创建PHP实现
    [PHP] 数据结构-循环链表的PHP实现
    [PHP] 数据结构-链表创建-插入-删除-查找的PHP实现
    [PHP] 算法-两个n位的二进制整数相加问题PHP实现
    [PHP] 数据结构-线性表的顺序存储结构PHP实现
    [日常] 链表-头结点和头指针的区别
    [日常] C语言中指针变量
    [日常] 算法-单链表的创建-尾插法
    [日常] 算法-单链表的创建
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3308832.html
Copyright © 2011-2022 走看看