用的FF算法,裸实现516ms++,记得当年的二分图16ms啊....
这里发两个模板吧,网络流才初学.. 弱爆了....
#include<iostream>
#include<cstdio>
#include<cmath>
#define MN 422
using namespace std;
struct edge
{ int f,c; }g[MN][MN];
struct node
{ int l,p,a; }list[MN];
int s,t,ans,M,N;
void init()
{
s=1;t=N+M+2;ans=0;
memset( g,0,sizeof(g) );
for( int i=1;i<=N;i++ )
{
g[s][i+1].c=1;
int n,u;
scanf( "%d",&n );
for( int j=1;j<=n;j++ )
{
scanf( "%d",&u );
g[i+1][N+u+1].c=1;
}
}
for( int i=1;i<=M;i++ )
g[i+N+1][t].c=1;
}
int find()
{
int i=1;
while( i<=N+M+2&&(list[i].l==0||list[i].p!=0) )i++;
if( i>N+M+2 ) return 0;
else return i;
}
bool ford()
{
memset( list,0,sizeof(list) );
list[s].l=s;
list[s].a=9999999;
while( list[t].l==0 )
{
int i=find();
if( i==0 ) return true;
for( int j=1;j<=N+M+2;j++ )
{
if( list[j].l==0 &&( g[j][i].c||g[i][j].c ) )
{
if( g[i][j].c-g[i][j].f )
{
list[j].l=i;
list[j].a=min(list[i].a,g[i][j].c-g[i][j].f);
}
if( g[j][i].f>0 )
{
list[j].l=-i;
list[j].a=min(list[i].a,g[j][i].f );
}
}
}
list[i].p=1;
}
ans+=list[t].a;
return false;
}
void change()
{
int j,m,a;
m=t;a=list[t].a;
while( m!=s )
{
j=m;m=abs(list[j].l);
if( list[m].l>0 ) g[m][j].f+=a;
if( list[m].l<0 ) g[j][m].f-=a;
}
}
void work()
{
bool p;
while(1)
{
p=ford();
if( p )
break;
else change();
}
printf( "%d\n",ans );
}
int main()
{
while( scanf("%d%d",&N,&M )!=EOF )
{
init();
work();
}
}
下面是匈牙利算法... 简洁啊....
#include<iostream>
using namespace std;
struct node
{
int link[201];
int length;
}point[201];
int N,M;
bool visited[201];
int match[201];
bool Match( int pre )
{
int i;
for( i=1;i<=point[pre].length;i++ )
{
if( !visited[point[pre].link[i]] ) //point[pre].link[i]
{
visited[point[pre].link[i]]=true;
if( match[point[pre].link[i]]==-1 || Match(match[point[pre].link[i]]) )
{
match[point[pre].link[i]]=pre;
return true;
}
}
}
return false;
}
int main()
{
while( scanf("%d %d",&N,&M )!=EOF )
{
memset( match,-1,sizeof(match) );
memset( point,0,sizeof(point) );
int i,j;
int num;
for( i=1;i<=N;i++ )
{
scanf( "%d",&point[i].length );
for( j=1;j<=point[i].length;j++ )
scanf( "%d",&point[i].link[j]);
}
int ans=0;
for( i=1;i<=M;i++ )
{
memset( visited,false,sizeof(visited) );
if( Match(i) ) ans++;
}
printf( "%d\n",ans );
}
return 0;
}