POJ 1274 网络流最大匹配

来源:互联网 发布:foxtable软件 编辑:程序博客网 时间:2024/06/06 08:31

用的FF算法,裸实现516ms++,记得当年的二分图16ms啊....

这里发两个模板吧,网络流才初学.. 弱爆了....

#include<iostream>#include<cstdio>#include<cmath>#define MN 422using 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;}