用的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; }