最小点覆盖 hdu--1054

来源:互联网 发布:c语言 实例 pdf 编辑:程序博客网 时间:2024/06/08 05:17

   点击打开题目链接

最小点覆盖=最大二分匹配的 (单向图) ;

最小点覆盖=最大二分匹配的一半 (双向图) ;

证明


   所以我们只需求最大匹配,用 匈牙利算法 求出最大匹配,除以二得到答案

 具体算法都已经给出相关链接;下面给出自己AC 代码

#include<stdio.h>#include<algorithm>#include<iostream>#include<string>#include<string.h>#include<stdlib.h>using namespace std;typedef long long int LL;const int MAXSIZE=10000;struct Edge{    int s,t;};Edge edge[MAXSIZE];int first[MAXSIZE],nexts[MAXSIZE];int link[MAXSIZE];bool vis[MAXSIZE];int tot;void init(){    memset(first,-1,sizeof(first));    memset(link,-1,sizeof(link));    tot=0;}void addedge(int s,int t){    edge[tot].s=s,edge[tot].t=t;    nexts[tot]=first[s];    first[s]=tot;    tot++;}int dfs(int now){    for(int i=first[now];i!=-1;i=nexts[i])    {        int to=edge[i].t;        if(!vis[to])        {            vis[to]=true;            if(link[to]==-1||dfs(link[to]))            {                link[to]=now;                return 1;            }        }    }    return 0;}int max_match(int n){    int ans=0;    for(int i=0;i<n;i++)    {        memset(vis,0,sizeof(vis));        ans+=dfs(i);    }    return ans;}int main(){    int n;    while(scanf("%d",&n)+1)    {        init();        for(int i=0;i<n;i++)        {            int t1,t2;            scanf("%d:(%d)",&t1,&t2);            while(t2--)            {                int num;                scanf("%d",&num);                addedge(t1,num);                addedge(num,t1);            }        }        printf("%d\n",max_match(n)>>1);    }    return 0;}


0 0
原创粉丝点击