最小点覆盖
/*
最小点覆盖为:在一个二分图中,选取最少的点可以把所有的变覆盖,
点的最少个数就是最小点覆盖。
最小点覆盖=最大二分匹配。
克鲁斯卡尔算法。
关于本题:
£:把从零开始,转化成从一开始。
£:起点不用加入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;
}
想的太多,做的太少。