POJ 1469,1274,2239,2536,2584,2446二分图的匈牙利算法(裸)
POJ1469
习惯性的不写return 0;这次尝到苦头了,很幸福的WA了……找了好久才知道是这个坏毛病……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int M=300; 8 bool vis[M]; 9 bool bmap[M][M]; 10 int cx[M],cy[M]; 11 int nx,ny; 12 int findpath(int u) 13 { 14 for(int i=0;i<ny;i++) 15 { 16 if(bmap[u][i]&&!vis[i]) 17 { 18 vis[i]=1; 19 if(cy[i]==-1||findpath(cy[i])) 20 { 21 cy[i]=u; 22 cx[u]=i; 23 return 1; 24 } 25 } 26 } 27 return 0;//勿忘了,没有就WA了 28 } 29 int MaxMatch() 30 { 31 int res=0; 32 for(int i=0;i<nx;i++) 33 cx[i]=-1; 34 for(int j=0;j<ny;j++) 35 cy[j]=-1; 36 for(int i=0;i<nx;i++) 37 { 38 if(cx[i]==-1) 39 { 40 for(int j=0;j<ny;j++) 41 vis[j]=0; 42 res+=findpath(i); 43 } 44 } 45 return res; 46 } 47 int main() 48 { 49 int T,t,k; 50 scanf("%d",&T); 51 while(T--) 52 { 53 scanf("%d%d",&nx,&ny); 54 memset(bmap,0,sizeof(bmap)); 55 for(int i=0;i<nx;i++) 56 { 57 scanf("%d",&t); 58 for(int j=0;j<t;j++) 59 { 60 scanf("%d",&k); 61 bmap[i][k-1]=1; 62 } 63 } 64 int ans=MaxMatch(); 65 if(ans==nx) 66 printf("YES\n"); 67 else 68 printf("NO\n"); 69 } 70 }
POJ1274
与1469几乎一样
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //poj1274 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 const int M=400; 9 int nx,ny; 10 int cx[M],cy[M]; 11 bool vis[M],bmap[M][M]; 12 int findpath(int u) 13 { 14 for(int i=0;i<ny;i++) 15 { 16 if(bmap[u][i]&&!vis[i]) 17 { 18 vis[i]=1; 19 if(cy[i]==-1||findpath(cy[i])) 20 { 21 cy[i]=u; 22 cx[u]=i; 23 return 1; 24 } 25 } 26 } 27 return 0; 28 } 29 int MaxMatch() 30 { 31 int res=0; 32 for(int i=0;i<nx;i++) 33 cx[i]=-1; 34 for(int j=0;j<ny;j++) 35 cy[j]=-1; 36 for(int i=0;i<nx;i++) 37 { 38 if(cx[i]==-1) 39 { 40 memset(vis,0,sizeof(vis)); 41 res+=findpath(i); 42 } 43 } 44 return res; 45 } 46 int main() 47 { 48 int t,k; 49 while(scanf("%d%d",&nx,&ny)!=EOF) 50 { 51 memset(bmap,0,sizeof(bmap)); 52 for(int i=0;i<nx;i++) 53 { 54 scanf("%d",&t); 55 for(int j=0;j<t;j++) 56 { 57 scanf("%d",&k); 58 bmap[i][k-1]=1; 59 } 60 } 61 printf("%d\n",MaxMatch()); 62 } 63 }
POJ2239
这个用链表写的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int M=310; 8 int nx,ny=7*12+1,cx[M],cy[M]; 9 int head[M],edgeNum; 10 bool vis[M]; 11 struct Edge 12 { 13 int v,next; 14 }edge[M*7*12]; 15 void add(int a,int b) 16 { 17 edge[edgeNum].v=b; 18 edge[edgeNum].next=head[a]; 19 head[a]=edgeNum++; 20 } 21 int findpath(int u) 22 { 23 for(int i=head[u];i!=-1;i= edge[i].next) 24 { 25 int v=edge[i].v; 26 if(!vis[v]) 27 { 28 vis[v]=1; 29 if (cy[v]==-1||findpath(cy[v])) 30 { 31 cy[v]=u; 32 cx[u]=v; 33 return 1; 34 } 35 } 36 } 37 return 0; 38 } 39 int MaxMatch() 40 { 41 int res=0; 42 for(int i=0;i<=nx;i++) 43 cx[i]=-1; 44 for(int j=0;j<=ny;j++) 45 cy[j]=-1; 46 for(int i=0;i<nx;i++) 47 { 48 if(cx[i]==-1) 49 { 50 for(int j=1;j<=ny;j++) 51 vis[j]=0; 52 res+=findpath(i); 53 } 54 } 55 return res; 56 } 57 int main() 58 { 59 int a,b,t; 60 while(scanf("%d",&nx)!=EOF) 61 { 62 edgeNum=0; 63 memset(head,-1,sizeof(head)); 64 for(int i=0;i<nx;i++) 65 { 66 scanf("%d",&t); 67 for(int j=0;j<t;j++) 68 { 69 scanf("%d%d",&a,&b); 70 add(i,(a-1)*12+b); 71 } 72 } 73 printf("%d\n",MaxMatch()); 74 } 75 }
POJ2536
因为一个小小的细节,本来是
cy[i]=u;
cx[u]=i;
return 1;
结果写成了
cy[i]=u;
cy[u]=i;
return 1;
WA了无数次,真的要认真了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int M=100; 8 int nx,ny; 9 int cx[M],cy[M]; 10 bool _map[M][M],vis[M]; 11 struct point{double x,y;}a[M],b[M]; 12 int findpath(int u) 13 { 14 int i,j; 15 for(i=0;i<ny;i++) 16 { 17 if(_map[u][i]&&!vis[i]) 18 { 19 vis[i]=1; 20 if(cy[i]==-1||findpath(cy[i])) 21 { 22 cy[i]=u; 23 cx[u]=i; 24 return 1; 25 } 26 } 27 } 28 return 0; 29 } 30 int MaxMatch() 31 { 32 int res=0; 33 int i,j; 34 for(i=0;i<nx;i++) 35 cx[i]=-1; 36 for(j=0;j<ny;j++) 37 cy[j]=-1; 38 for(i=0;i<nx;i++) 39 { 40 if(cx[i]==-1) 41 { 42 for(j=0;j<ny;j++) 43 vis[j]=0; 44 res+=findpath(i); 45 } 46 } 47 return res; 48 } 49 int main() 50 { 51 int s,v; 52 while(scanf("%d%d%d%d",&nx,&ny,&s,&v)!=EOF) 53 { 54 for(int i=0;i<nx;i++) 55 scanf("%lf%lf",&a[i].x,&a[i].y); 56 for(int j=0;j<ny;j++) 57 scanf("%lf%lf",&b[j].x,&b[j].y); 58 s=s*s*v*v; 59 //memset(_map,0,sizeof(_map)); 60 for(int i=0;i<nx;i++) 61 for(int j=0;j<ny;j++) 62 { 63 double r=(a[i].x-b[j].x)*(a[i].x-b[j].x)+(a[i].y-b[j].y)*(a[i].y-b[j].y); 64 if( r<=s ) 65 { 66 _map[i][j]=1; 67 } 68 else 69 _map[i][j]=0; 70 } 71 printf("%d\n",nx-MaxMatch()); 72 } 73 return 0; 74 }
POJ2584
这道题我是把每一件衣服看成一个点,所有的衣服是一个集合,所有的人是一个集合,裸的匈牙利算法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //poj2584 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 const int M=105; 9 int nx,ny; 10 int cx[M],cy[M]; 11 bool _map[M][M],vis[M]; 12 int F(char c) 13 { 14 switch(c) 15 { 16 case 'S':return 1;break; 17 case 'M':return 2;break; 18 case 'L':return 3;break; 19 case 'X':return 4;break; 20 case 'T':return 5;break; 21 default:return 0; 22 } 23 } 24 int findpath(int u) 25 { 26 int i,j; 27 for(i=0;i<ny;i++) 28 { 29 if(_map[u][i]&&!vis[i]) 30 { 31 vis[i]=1; 32 if(cy[i]==-1||findpath(cy[i])) 33 { 34 cy[i]=u; 35 cx[u]=i; 36 return 1; 37 } 38 } 39 } 40 return 0; 41 } 42 int MaxMatch() 43 { 44 int res=0; 45 int i,j; 46 for(i=0;i<nx;i++) 47 cx[i]=-1; 48 for(j=0;j<ny;j++) 49 cy[j]=-1; 50 for(i=0;i<nx;i++) 51 { 52 if(cx[i]==-1) 53 { 54 for(j=0;j<ny;j++) 55 vis[j]=0; 56 res+=findpath(i); 57 } 58 } 59 return res; 60 } 61 int main() 62 { 63 char ch[20]; 64 char st[100][2]; 65 int tmp; 66 int f[10][2]; 67 while(scanf("%s",ch)!=EOF) 68 { 69 if(strcmp(ch,"ENDOFINPUT")==0) break; 70 memset(_map,0,sizeof(_map)); 71 scanf("%d",&nx); 72 getchar(); 73 for(int i=0;i<nx;i++) 74 { 75 scanf("%s",st[i]); 76 } 77 int sum=0; 78 for(int i=1;i<=5;i++) 79 { 80 scanf("%d",&tmp); 81 if(tmp!=0) 82 { 83 f[i][0]=sum+1; 84 sum+=tmp; 85 f[i][1]=sum; 86 } 87 else 88 { 89 f[i][0]=f[i][1]=-1; 90 } 91 } 92 ny=sum+2; 93 for(int i=0;i<nx;i++) 94 { 95 for(int j=F(st[i][0]);j<=F(st[i][1]);j++) 96 { 97 if(f[j][0]==-1) continue; 98 for(int k=f[j][0];k<=f[j][1];k++) 99 { 100 _map[i][k]=1; 101 } 102 } 103 104 } 105 scanf("%s",ch); 106 int res=MaxMatch(); 107 if(res==nx) 108 printf("T-shirts rock!\n"); 109 else 110 printf("I'd rather not wear a shirt anyway...\n"); 111 112 } 113 }
POJ2446
一开始建图建错了,应该说是建重了,多建立了一些边。把i+j的奇数看成一个集合,把i+j的偶数看成一个集合
虽然图画的丑了点,但是理解起来还是挺好的。
而且数组开小了,所以WA了两次:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int M=2010; 8 int nx,ny; 9 int cx[M],cy[M]; 10 bool _map[M][M],vis[M]; 11 bool hp[100][100]; 12 int findpath(int u) 13 { 14 int i,j; 15 for(i=0;i<ny;i++) 16 { 17 if(_map[u][i]&&!vis[i]) 18 { 19 vis[i]=1; 20 if(cy[i]==-1||findpath(cy[i])) 21 { 22 cy[i]=u; 23 cx[u]=i; 24 return 1; 25 } 26 } 27 } 28 return 0; 29 } 30 int MaxMatch() 31 { 32 int res=0; 33 int i,j; 34 for(i=0;i<nx;i++) 35 cx[i]=-1; 36 for(j=0;j<ny;j++) 37 cy[j]=-1; 38 for(i=0;i<nx;i++) 39 { 40 if(cx[i]==-1) 41 { 42 for(j=0;j<ny;j++) 43 vis[j]=0; 44 res+=findpath(i); 45 } 46 } 47 return res; 48 } 49 int m,n,k; 50 int move[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; 51 int check(int x,int y) 52 { 53 if(x>=0&&x<m&&y>=0&&y<n&&!hp[x][y]) return 1; 54 return 0; 55 } 56 int main() 57 { 58 int x,y; 59 while(scanf("%d%d%d",&m,&n,&k)!=EOF) 60 { 61 memset(hp,0,sizeof(hp)); 62 memset(_map,0,sizeof(_map)); 63 for(int i=0;i<k;i++) 64 { 65 scanf("%d%d",&x,&y); 66 hp[y-1][x-1]=1; 67 } 68 if((m*n-k)&1){printf("NO\n");continue;} 69 nx=ny=m*n; 70 for(int i=0;i<m;i++) 71 for(int j=0;j<n;j++) 72 { 73 //printf("%d %d:\n",i,j); 74 if((i+j)&1) 75 if(!hp[i][j]) 76 for(int k=0;k<4;k++) 77 { 78 x=i+move[k][0]; 79 y=j+move[k][1]; 80 if(check(x,y)) 81 { 82 _map[i+j*m][x+y*m]=1; 83 //printf("map[%d][%d]\n",i+j*m,x+y*m); 84 } 85 } 86 } 87 int ans=MaxMatch(); 88 if(ans*2==m*n-k) 89 printf("YES\n"); 90 else 91 printf("NO\n"); 92 } 93 return 0; 94 }