POJ 1469,1274,2239,2536,2584,2446二分图的匈牙利算法(裸)

POJ1469

习惯性的不写return 0;这次尝到苦头了,很幸福的WA了……找了好久才知道是这个坏毛病……

View Code
 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几乎一样

View Code
 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
这个用链表写的

View Code
 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了无数次,真的要认真了

View Code
 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

这道题我是把每一件衣服看成一个点,所有的衣服是一个集合,所有的人是一个集合,裸的匈牙利算法

View Code
  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了两次:

View Code
 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 }

 

posted @ 2012-08-05 19:47  _sunshine  阅读(430)  评论(0编辑  收藏  举报