最小覆盖点集模板

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int N=1111;

int n1,n2,k;

int mp[N][N],vis[N],link[N];
int vis2[N];
int v[N];

int dfs(int x)
{
    int i;
    vis2[x]=1;
    for(i=1; i<=n2; i++)
    {
        if(!mp[x][i]&&!vis[i])
        {
            vis[i]=1;
            if(link[i]==-1||dfs(link[i]))
            {
                link[i]=x;
                return 1;
            }
        }
    }
    return 0;
}

int main()

{

    int i,x,y,s;
    int cas = 0;
    while(scanf("%d%d%d",&n1,&n2,&k)&&n1){
        s=0;
        for(int i=1;i<=n1;i++){
            for(int j=1;j<=n2;j++){
               mp[i][j]=1;
            }
        }

        for(i=0; i<k; i++)
        {
            scanf("%d%d",&x,&y);
            mp[x][y]=0;
        }

        memset(link,-1,sizeof(link));

        for(i=1; i<=n1; i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i))
            s++;
        }

        memset(vis,0,sizeof(vis));
        memset(vis2,0,sizeof(vis2));
        memset(v,0,sizeof(v));

        for(int i=1;i<=n2;i++){
            v[link[i]]=1;
           //printf("link[%d] :%d\n",i,link[i]);
        }
        for(int i=1;i<=n1;i++){
            if(!v[i])
                dfs(i);
        }
        printf("%d",s);
        //左边覆盖点
        for(int i=1;i<=n1;i++){
            if(!vis2[i])
            printf(" r%d",i);
        }
        //右边覆盖点
        for(int i=1;i<=n2;i++){
            if(vis[i])
            printf(" c%d",i);
        }
        puts("");
    }
    return 0;
}
时间: 2024-10-09 07:31:52

最小覆盖点集模板的相关文章

最小路径覆盖,最小点覆盖,最大独立点集

原文地址:http://blog.csdn.net/l04205613/article/details/6278394 node  1:最小路径覆盖 在一个PXP的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联:(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次):如果不考虑图中存在回路,那么每条路径就是一个弱连通子集.由上面可以得出:1.一个单独的顶点是一条路径:2.如果存在一路径p1,p2

最小路径覆盖,最小点覆盖,最大独立点集(转)

来自:http://blog.csdn.net/l04205613/article/details/6278394 node  1:最小路径覆盖 在一个PXP的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的 所有顶点,且任何一个顶点有且只有一条路径与之关联:(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一 次):如果不考虑图中存在回路,那么每条路径就是一个弱连通子集. 由上面可以得出: 1.一个单独的顶点是一条路径: 2.如果存在一路径p1

图论之二分图匹配

一.二分图最大匹配 Edmonds于1965年提出了匈牙利算法,解决了求取二分图最大匹配的问题.其算法思想是将初始匹配通过迭代寻找增广路径得到最大匹配,每次迭代得到的匹配大小加1. 增广路径的表现形式是一条“交错路径”,第一条边是目前没有参与匹配的,第二条参与匹配,第四条边没有参与......最后一条边没有参与匹配,并且始点和终点还没有被选过.那么对于这样一条路径,我们可以将第一条边改为已匹配,第二条边改为未匹配...以此类推.也就是将所有的边进行"反色",容易发现这样修改以后,匹配仍

【网络流】hdu 1569 方格取数(2)

/* 和1565一样: 总点数的权 - 最小覆盖点集 = 最大独立集 -------------------------------------- void add(int u, int v, int f)加边 { e[ct].u = u; e[ct].v = v; e[ct].f = f; next[ct] = first[u]; first[u] = ct++; e[ct].u = v; e[ct].v = u; e[ct].f = 0; next[ct] = first[v]; first

HDU 1054 Strategic Game 最小点覆盖

 最小点覆盖概念:选取最小的点数覆盖二分图中的所有边. 最小点覆盖 = 最大匹配数. 证明:首先假设我们求的最大匹配数为m,那么最小点覆盖必然 >= m,因为仅仅是这m条边就至少需要m个点.然后假如我们已经求得最小覆盖点集,那么在点集中每个点必然有着这样的性质,在于它相连的边里面,一定有一条边的端点不在最小点集中,因为如果连一条这样的边都没有,那这个点完全没有在最小点集的必要,我们任意选取这样的一条边,一定可以形成一个匹配,匹配数与最小点集中的点的个数相等,但现在这仅仅是一个匹配,他必然小于最大

二分图中的最大匹配数等于最小点覆盖数的证明

转载自Matrix67 二分图最大匹配的K?nig定理及其证明 如果你看不清楚第二个字母,下面有一个大号字体版本: 二分图最大匹配的K?nig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K?nig定理证了,其它的废话一概没有.    以下五个问题我可能会在以后的文章里说,如果你现在很想知道的话,网上去找找答案:    1. 什么是二分图:    2. 什么是二分图的匹配:    3. 什么是匈牙利算法:(http://www.matrix67.com/blog/article.as

怎样使用OpenShare部署和运营企业门户

怎样使用OpenShare部署和运营企业门户 这篇Blog是偏向企业内总体门户部署和运营的指南,是偏向总体管理和规划的.并非针对终端用户的OpenShare软件操作手冊,详细的操作能够上优酷看相关视频. 基础概念:站点是OpenShare企业门户的载体 从根本上讲,使用OpenShare构造的企业门户.其基本载体是站点:文档.联系人,大数据,流程,应用等等等等的全部内容和功能都通过站点这个载体得以体现.比方: 一个项目组要进行协作,那么做法就是基于"项目站点"模板建立一个这个项目组专属

二分图最小路径覆盖--poj2060 Taxi Cab Scheme

Taxi Cab Scheme 时间限制: 1 Sec  内存限制: 64 MB 题目描述 Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coordination of the cabs in order to pick up the customers calling to get a cab as soon as possible,there is

满世界都是图论

最近开始接触图论,对图论理解可能有不对的地方,欢迎指正! 刚刚看图论可能觉得有些无趣,满满都是概念和证明,几个引理后面跟几个定理.但如果暂时跳过这些繁冗复杂的东西,先去看看这些理论的定理和算法有哪些应用,就顿时发现图论真是个有趣的东西~ 1. 图的连通性 首先“连通图”很容易理解,比如这个世界每个人做一个节点的话,把相互认识的两人间连一条线,整张图多半可能就是一张连通图. 对于一个连通图G,就产生了两个概念:特征路径步长和聚合系数 特征路径长度(characteristic path lengt