• (匹配 最小路径覆盖)Air Raid --hdu --1151


    链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1151

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82834#problem/J

    /* **************************************************************************
    //二分图匹配(匈牙利算法的DFS实现) //初始化:G[][]两边顶点的划分情况 //建立G[i][j]表示i->j的有向边就可以了,是左边向右边的匹配 //G没有边相连则初始化为0 //uN是匹配左边的顶点数,vN是匹配右边的顶点数 //调用:res=hungary();输出最大匹配数 //优点:适用于稠密图,Find找增广路,实现简洁易于理解 //时间复杂度:O(VE)
    //顶点编号从0开始的
    //************************************************************************** */

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 205
    #define INF 0x3f3f3f3f
    
    int n, m, un, vn, G[N][N], used[N], p[N];
    
    int Find(int u)
    {
        for(int i=0; i<vn; i++)
        {
            if(G[u][i] && !used[i])
            {
                used[i] = 1;
                if(p[i]==-1 || Find(p[i]))
                {
                    p[i] = u;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    void hungary()
    {
        int ans = 0;
        memset(p, -1, sizeof(p));
    
        for(int i=0; i<un; i++)
        {
            memset(used, 0, sizeof(used));
            if(Find(i)) ans++;
        }
    
        printf("%d
    ", n-ans);
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t--)
        {
            int i, u, v;
    
            scanf("%d%d", &n, &m);
    
            memset(G, 0, sizeof(G));
            for(i=1; i<=m; i++)
            {
                scanf("%d%d", &u, &v);
                u--, v--;
                G[u][v] = 1;
            }
            un = vn = n;
    
            hungary();
        }
        return 0;
    }

    最小顶点覆盖:在二分图中寻找一个尽量小的点集,使图中每一条边至少有一个点在该点集中。

      最小顶点覆盖 == 最大匹配。

      反证法证明:假设当前存在一条两个端点都不在最小顶点覆盖点集中,那么这么光芒四射的边定可以增大最大匹配边集,与最大匹配矛盾,所以得证。

     

    最小路径覆盖:在二分图中寻找一个尽量小的边集,使图中每一个点都是该边集中某条边的端点。

      最小路径覆盖 == 顶点数 - 最大匹配。

      证明:因为一条边最多可以包含两个顶点,所以我们选边的时候让这样的边尽量多,也就是说最大匹配的边集数目咯。剩下的点就只能一个边连上一个点到集合里啦。

     

    最大独立集:在N个点中选出来一个最大点集,使这个点集中的任意两点之间都没有边。

      最大独立集 == 顶点数 - 最大匹配。

      证明:因为去掉最大匹配两端的顶点去掉以后,剩下的点肯定是独立集。我们再从每个匹配里面挑选出来一个点加入到独立集中,也是不会破坏原有独立集的独立性的。

    勿忘初心
  • 相关阅读:
    [GO]使用bufio的文件读取方式
    php开发工程师面必问题
    一位资深php程序员在北京的面试30个题目
    GIT 分支管理:创建与合并分支、解决合并冲突
    linux下挂在u盘,移动硬盘的方法,转移服务器资料的时候,使用移动硬盘什么最方便了
    php后台对接ios,安卓,API接口设计和实践完全攻略,涨薪必备技能
    navicat 官方使用手册,中文版,快捷键大全
    Memcached之缓存雪崩,缓存穿透,缓存预热,缓存算法
    Memcache 笔记(2)
    Memcache笔记(1)
  • 原文地址:https://www.cnblogs.com/YY56/p/4719956.html
Copyright © 2020-2023  润新知