最小点覆盖 hdu--1054

   点击打开题目链接

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

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

证明


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

 具体算法都已经给出相关链接;下面给出自己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
",max_match(n)>>1);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/coded-ream/p/7207962.html