最小顶点覆盖!匈牙利算法
最小顶点覆盖 == 最大匹配(双向图)/2; (题目给的是单向的,添加反向边就行了)
此题有个小细节,数据较大,邻接矩阵会超时,要用邻接表! 用的是数组模拟的,250MS。

#include<iostream>
using namespace std;
int n;
int count;
int ok[1510];
int Right[1510];
int m;
int from,to;
int head[1510];
int ID;
struct Edge
{
int u;
int v;
int next;
}e[20000];
bool path(int k);
int main()
{
while(cin>>n)
{
memset(ok,-1,sizeof(ok));
count=0;
for(int i=0;i<n;i++)
head[i]=-1;
ID=0;
for(i=0;i<n;i++)
{
scanf("%d:(%d)",&from,&m);
for(int j=0;j<m;j++)
{
scanf("%d",&to);
e[ID].u=from;
e[ID].v=to;
e[ID].next=head[from];
head[from]=ID++;
e[ID].u=to;
e[ID].v=from;
e[ID].next=head[to];
head[to]=ID++;
}
}
for(i=0;i<n;i++)
{
memset(Right,0,sizeof(Right));
if(path(i))
count++;
}
cout<<count/2<<endl;
}
return 0;
}
bool path(int k)
{
for(int i=head[k];i!=-1;i=e[i].next)
{
if(Right[e[i].v]==0)
{
Right[e[i].v]=1;
if( ok[e[i].v]==-1 || path(ok[e[i].v]) )
{
ok[e[i].v]=k;
return true;
}
}
}
return false;
}