• zoj 1134


    题目:给你一棵树。找到最小的顶点集合,使得全部的边至少有一个顶点在这个集合中。

    分析:树形dp,图论,最小顶点覆盖。

                方案1:树形dp。分别记录每一个节点取和不取的最优解f(k。0)与f(k,1);

                              每一个节点的状态取决于子树,子树的根都不选,则他必选;否则取最小;

                              f(k。0)= sum(f(i,1))。 

                              f(k。1)= sum(min(f(i,0)。f(i。1))){ 当中 i 是k的子树根节点 };

                方案2:最小顶点覆盖 = N - 最大独立点 = 最大匹配。

    说明:(2011-09-19 09:46)。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define min(x,y) ((x)<(y)?(x):(y))
    
    typedef struct node
    {
        int Count;
        int Value;
        int    Next[ 10 ];
    }node;
    node Node[ 1510 ];
    int  Root;
    
    typedef struct answ
    {
        int sum0;
        int sum1;
    }Answ;
    Answ Save;
    
    Answ dp( int Root )
    {
        Answ an;
             an.sum0 = 0;
             an.sum1 = 1;
        if ( Node[ Root ].Count ) {
            for ( int i = 0 ; i < Node[ Root ].Count ; ++ i ) {
                Save = dp( Node[ Root ].Next[ i ] );
                an.sum0 += Save.sum1;
                an.sum1 += min( Save.sum0, Save.sum1 );
            }
        }
        return an;
    }
    
    int main()
    {
        int n,a,m,b;
        while ( scanf("%d",&n) != EOF ) {
            Root = -1; 
            memset( Node, 0, sizeof( Node ) );
            for ( int i = 0 ; i < n ; ++ i ) {
                scanf("%d:(%d)",&a,&m); 
                if ( Root == -1 ) Root = a;
                Node[ a ].Count = m;
                Node[ a ].Value = a;
                for ( int j = 0 ; j < m ; ++ j ) {
                    scanf("%d",&b);
                    Node[ a ].Next[ j ] = b;
                }
            }
            Answ answer = dp( Root );
            printf("%d
    ",min( answer.sum0, answer.sum1 ));
        }
        return 0;
    }
    图论解法:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node
    {
        int     Point;
        node*    Next;
    }node;
    node  Node[ 3001 ];
    node *Head[ 1501 ];
    bool  Used[ 1501 ];
    int   Result[ 1501 ];
    
    bool find( int a, int n )
    {
        for ( node *P = Head[ a ] ; P ; P = P->Next ) 
            if ( !Used[ P->Point ] ) {
                Used[ P->Point ] = true;
                if ( Result[ P->Point ] == -1 || find( Result[ P->Point ] , n ) ) {
                    Result[ P->Point ] = a;
                    return true;
                }
            }
        return false;
    }
    
    int argument( int n )
    {
        for ( int i = 0 ; i < n ; ++ i )
            Result[ i ] = -1;
        int Count = 0;
        for ( int i = 0 ; i < n ; ++ i ) {
            for ( int j = 0 ; j < n ; ++ j )
                Used[ j ] = false;
            if ( find( i, n ) )
                ++ Count;
        }
        return Count;
    }
    
    int main()
    {
        int n,a,m,b;
        while ( scanf("%d",&n) != EOF ) {
            for ( int i = 0 ; i < n ; ++ i )
                Head[ i ] = NULL;
            int Count = 0;
            for ( int i = 0 ; i < n ; ++ i ) {
                scanf("%d:(%d)",&a,&m); 
                for ( int j = 0 ; j < m ; ++ j ) {
                    scanf("%d",&b);
                    Node[ Count ].Next  = Head[ a ];
                    Node[ Count ].Point = b;
                    Head[ a ] = &Node[ Count ++ ];
                    Node[ Count ].Next  = Head[ b ];
                    Node[ Count ].Point = a;
                    Head[ b ] = &Node[ Count ++ ];
                }
            }
            printf("%d
    ",argument( n )/2);
        }
        return 0;
    }

  • 相关阅读:
    React.memo()使用教程
    React组件什么时候render
    redux-thunk使用教程
    Redux数据持久化
    Mac 中安装 nvm: 切换Node 不同版本
    上传文件类型选择
    Python获取软件安装列表
    Java读取text文件
    负载均衡
    远程调用
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5094669.html
Copyright © 2020-2023  润新知