Hdu 3605 多重匹配

题意:

给出每个人适合住的星球信息和该星球能住多少人 

第一行给出n m 代表有 n 个人 m 个星球

然后接下来n行每行m个数字 1代表适合第 i 个星球 0 代表不适合第 i 个星球

最后一行m个数表示第 i 个星球最多可以住多少个人

问是不是所有人都可以住到星球上

思路:

多重匹配

Tips:

多重匹配即 X 集合上的点对应 Y 集合上多个点 而 Y 集合上的点对应 X 中的一个点

Code:

View Code
 1 #include <stdio.h>
 2 #include <cstring>
 3 #define clr(x) memset(x, 0, sizeof(x))
 4 const int INF = 0x1f1f1f1f;
 5 
 6 bool G[100010][15];
 7 int limit[15];
 8 bool vis[15];
 9 int v1, v2;
10 int v[15];
11 int vv[15][100010];
12 
13 bool find(int u)
14 {
15     int i, j, k;
16     for(i = 0; i < v2; ++i) {
17         if(G[u][i] && !vis[i]) {
18             vis[i] = true;
19             if(v[i] < limit[i]) {
20                 vv[i][v[i]++] = u;
21                 return true;
22             }
23 
24             for(j = 0; j < v[i]; ++j) {
25                 if(find(vv[i][j])) {
26                     vv[i][j] = u;
27                     return true;
28                 }
29             }
30         }
31     }
32     return false;
33 }
34 
35 bool solve()
36 {
37     clr(v), clr(vv);
38     for(int i = 0; i < v1; ++i) {
39         clr(vis);
40         if(!find(i)) {
41             return false;
42         }
43     }
44     return true;
45 }
46 
47 int main()
48 {
49     int i, j, k;
50     while(scanf("%d %d", &v1, &v2) != EOF)
51     {
52         clr(G);
53 
54         for(i = 0; i < v1; ++i)
55         for(j = 0; j < v2; ++j) {
56             scanf("%d", &G[i][j]);
57         }
58         for(i = 0; i < v2; ++i)
59             scanf("%d", &limit[i]);
60 
61         if(solve()) puts("YES");
62         else puts("NO");
63     }
64 
65     return 0;
66 }

 

 

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605

posted @ 2012-09-17 20:24  Griselda.  阅读(612)  评论(0编辑  收藏  举报