hdu 1054 Strategic Game 最小顶点覆盖(二分图最大匹配)

来源:互联网 发布:淘宝免费开店是真的吗 编辑:程序博客网 时间:2024/05/29 18:27

题意:

给出多个点和某些点的连线。询问可以通过最少多少个点,看到所有叶子

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include <vector>#include<algorithm>using namespace std;const int maxn=1505;int n,m;int pre[maxn];//保存各点的匹配点int vis[maxn];int voc[maxn];vector<int> vec[maxn];int find(int u)//判断是否存在增广路,存在返回1{    int i,v;    for(i=0;i<vec[u].size();i++)    {        v=vec[u][i];        if(vis[v])continue;        vis[v]=1;        if(pre[v]==-1||find(pre[v]))//-1找到未盖点,find是增广路。        {            pre[v]=u;//匹配边和非匹配边交换            voc[v]=u;            voc[u]=v;            return 1;        }    }    return 0;}int main(){    while(scanf("%d",&n)!=EOF)    {        int u,v;        memset(pre,-1,sizeof(pre));        for(int i=0;i<n;i++)            vec[i].clear();        for(int i=0;i<n;i++)        {            scanf("%d:(%d)",&u,&m);            for(int j=0;j<m;j++)            {                scanf("%d",&v);                vec[v].push_back(u);                vec[u].push_back(v);            }        }        memset(voc,-1,sizeof(voc));        int ans=0;        for(int i=0;i<n;i++)        {            memset(vis,0,sizeof(vis));            ans+=find(i);        }/*        for(int i=0;i<n;i++)        {            if(i==voc[voc[i]])            printf("%d %d\n",i,voc[i]);            else                printf("%d -1\n",i);        }*/        printf("%d\n",ans/2);    }    return 0;}/*53:(3) 1 4 21:(1) 02:(0)0:(1) 24:(0)*/


0 0