最小点覆盖

题目连接

/*
    最小点覆盖为:在一个二分图中,选取最少的点可以把所有的变覆盖,
    点的最少个数就是最小点覆盖。
    最小点覆盖=最大二分匹配。
    克鲁斯卡尔算法。
    关于本题:
    £:把从零开始,转化成从一开始。
    £:起点不用加入E[],因为机器的起始状态就是1,或者加入E[]但是不参加计算,(我采用的是第二种。)
*/
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=100+50;
int k,n,m;
vector<int>E[maxn];
int f[maxn];
bool vis[maxn];
int ans;
bool match(int x)
{
    int l=(int)E[x].size();
    for(int i=0;i<l;i++)
    {
        int t=E[x][i];
        if(!vis[t])
        {
            vis[t]=true;
            if(f[t]==-1||match(f[t]))
            {
                f[t]=x;
                return true;
            }
        }
    }
    return false;
}
int hungary()
{
    ans=0;
    memset(f,-1,sizeof(f));
    for (int i=2;i<=n;i++)
    {
        memset(vis, false, sizeof(vis));
        if(match(i))
            ans++;
    }
    return ans;
}
int main ()
{
    while(scanf("%d",&n),n)
    {
        scanf("%d%d",&m,&k);
        int I,a,b;
        for(int i=0;i<=n;i++)
            E[i].clear();
        for(int i=0;i<k;i++)
        {
            scanf("%d%d%d",&I,&a,&b);
            E[a+1].push_back(b+1);
        }
        int ans=hungary();
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2016-08-07 19:47  _Mickey  阅读(1095)  评论(0编辑  收藏  举报