HDU 3605 Escape(二分图多重匹配问题)

Escape

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 10382    Accepted Submission(s): 2485

Problem Description

2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets.

Input

More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most..
0 <= ai <= 100000

Output

Determine whether all people can live up to these stars
If you can output YES, otherwise output NO.

Sample Input

1 1

1

1

2 2

1 0

1 0

1 1

Sample Output

YES

NO

Source

2010 ACM-ICPC Multi-University Training Contest(17)——Host by ZSTU

Recommend

lcy

题意:

  给你n个人m个星球,和第i个人能否适应第j个星球,1为适应,0为不适应。问你全部人能不能去星球上。

  矩阵建边,跑一下二分图多重匹配。如果这个人无法去任意星球,直接break。

  

普通版:1560ms

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 #define ms(a, b) memset(a, b, sizeof(a))
15 #define pb push_back
16 #define mp make_pair
17 const LL INF = 0x7fffffff;
18 const int inf = 0x3f3f3f3f;
19 const int mod = 1e9+7;
20 const int maxn = 100000+10;
21 const int maxm = 10+10;
22 int n, m, uN, vN;
23 int g[maxn][maxm];
24 int linker[maxm][maxn];
25 bool used[maxm];
26 int num[maxm];
27 bool dfs(int u)
28 {
29     for(int v = 0;v<vN;v++)
30         if(g[u][v] && !used[v]){
31             used[v] = true;
32             if(linker[v][0]<num[v]){
33                 linker[v][++linker[v][0]] = u;
34                 return true;
35             }
36             for(int i = 1;i<=num[0];i++)
37                 if(dfs(linker[v][i])){
38                     linker[v][i] = u;
39                     return true;
40                 }
41         }
42     return false;
43 }
44 int hungary()
45 {
46     int res = 0;
47     for(int i = 0;i<vN;i++){
48         linker[i][0] = 0;
49     }
50     for(int u = 0;u<uN;u++){
51         ms(used, false);
52         if(dfs(u))  res++;
53         else return res;
54     }
55     return res;
56 }
57 void init() {
58     ms(g, 0);
59 }
60 void solve() {
61     for(int i = 0;i<n;i++){
62         for(int j = 0;j<m;j++){
63             int x;
64             scanf("%d", &x);
65             if(x==1){
66                 g[i][j] = 1;
67             }
68             else{
69                 g[i][j] = 0;
70             }
71         }
72     }
73     for(int i = 0;i<m;i++)
74         scanf("%d", &num[i]);
75     vN = m, uN = n;
76     int ans = hungary();
77 //    printf("%d\n", ans);
78     if(ans==n){
79         printf("YES\n");
80     }
81     else{
82         printf("NO\n");
83     }
84 }
85 int main() {
86 #ifdef LOCAL
87     freopen("input.txt", "r", stdin);
88 //        freopen("output.txt", "w", stdout);
89 #endif
90     while(~scanf("%d%d", &n, &m)){
91         init();
92         solve();
93     }
94     return 0;
95 }

fread版:249ms

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <vector>
  8 #include <queue>
  9 #include <map>
 10 #include <stack>
 11 #include <set>
 12 using namespace std;
 13 typedef long long LL;
 14 #define ms(a, b) memset(a, b, sizeof(a))
 15 #define pb push_back
 16 #define mp make_pair
 17 const LL INF = 0x7fffffff;
 18 const int inf = 0x3f3f3f3f;
 19 const int mod = 1e9+7;
 20 const int maxn = 100000+10;
 21 const int maxm = 10+10;
 22 //输入挂
 23 const int MAXBUF = 10000;
 24 char buf[MAXBUF], *ps = buf, *pe = buf+1;
 25 inline void rnext()
 26 {
 27     if(++ps == pe)
 28         pe = (ps = buf)+fread(buf,sizeof(char),sizeof(buf)/sizeof(char),stdin);
 29 }
 30 template <class T>
 31 inline bool in(T &ans)
 32 {
 33     ans = 0;
 34     T f = 1;
 35     if(ps == pe) return false;//EOF
 36     do{
 37         rnext();
 38         if(‘-‘ == *ps) f = -1;
 39     }while(!isdigit(*ps) && ps != pe);
 40     if(ps == pe) return false;//EOF
 41     do
 42     {
 43         ans = (ans<<1)+(ans<<3)+*ps-48;
 44         rnext();
 45     }while(isdigit(*ps) && ps != pe);
 46     ans *= f;
 47     return true;
 48 }
 49 const int  MAXOUT=10000;
 50 char bufout[MAXOUT], outtmp[50],*pout = bufout, *pend = bufout+MAXOUT;
 51 inline void write()
 52 {
 53     fwrite(bufout,sizeof(char),pout-bufout,stdout);
 54     pout = bufout;
 55 }
 56 inline void out_char(char c){ *(pout++) = c;if(pout == pend) write();}
 57 inline void out_str(char *s)
 58 {
 59     while(*s)
 60     {
 61         *(pout++) = *(s++);
 62         if(pout == pend) write();
 63     }
 64 }
 65 template <class T>
 66 inline void out_int(T x) {
 67     if(!x)
 68     {
 69         out_char(‘0‘);
 70         return;
 71     }
 72     if(x < 0) x = -x,out_char(‘-‘);
 73     int len = 0;
 74     while(x)
 75     {
 76         outtmp[len++] = x%10+48;
 77         x /= 10;
 78     }
 79     outtmp[len] = 0;
 80     for(int i = 0, j = len-1; i < j; i++,j--) swap(outtmp[i],outtmp[j]);
 81     out_str(outtmp);
 82 }
 83 //end
 84 int n, m, uN, vN;
 85 int g[maxn][maxm];
 86 int linker[maxm][maxn];
 87 bool used[maxm];
 88 int num[maxm];
 89 bool dfs(int u)
 90 {
 91     for(int v = 0;v<vN;v++)
 92         if(g[u][v] && !used[v]){
 93             used[v] = true;
 94             if(linker[v][0]<num[v]){
 95                 linker[v][++linker[v][0]] = u;
 96                 return true;
 97             }
 98             for(int i = 1;i<=num[0];i++)
 99                 if(dfs(linker[v][i])){
100                     linker[v][i] = u;
101                     return true;
102                 }
103         }
104     return false;
105 }
106 int hungary()
107 {
108     int res = 0;
109     for(int i = 0;i<vN;i++){
110         linker[i][0] = 0;
111     }
112     for(int u = 0;u<uN;u++){
113         ms(used, false);
114         if(dfs(u))  res++;
115         else return res;
116     }
117     return res;
118 }
119 void init() {
120     ms(g, 0);
121 }
122 void solve() {
123     int x;
124     for(int i = 0;i<n;i++){
125         for(int j = 0;j<m;j++){
126             in(x);
127             if(x==1){
128                 g[i][j] = 1;
129             }
130             else{
131                 g[i][j] = 0;
132             }
133         }
134     }
135     for(int i = 0;i<m;i++)
136         in(num[i]);
137     vN = m, uN = n;
138     int ans = hungary();
139     if(ans==n){
140         out_str("YES");out_char(‘\n‘);
141     }
142     else{
143         out_str("NO");out_char(‘\n‘);
144     }
145 }
146 int main() {
147 #ifdef LOCAL
148     freopen("input.txt", "r", stdin);
149 //        freopen("output.txt", "w", stdout);
150 #endif
151     while(in(n)&&in(m)){
152         init();
153         solve();
154     }
155     write();
156     return 0;
157 }

时间: 2024-12-25 19:30:38

HDU 3605 Escape(二分图多重匹配问题)的相关文章

hdu 3605 Escape (二分图多重匹配)

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4298    Accepted Submission(s): 1129 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

HDU 3605 Escape(多重匹配之多对多的匹配)

题意:N个人要要到M个星球上去,告诉每个人可以去哪些星球,以及每个 星球可以住的人数,问所有的人时候都可以安排完 这题和 HDU1669差不多,HDU1669是一对多的匹配,这是多对多的匹配,一对多的匹配是大家的limit都是一样的,多对多的匹配是大家的limit不都一样,每个人有自己的limit,所以开个数组记录每个人的limit #include<cstdio> #include<iostream> #include<algorithm> #include<c

hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 8001    Accepted Submission(s): 1758 Problem Description 2012 If this is the end of th

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

hdoj 3605 Escape 【中等最大流 | 二分图多重匹配】

题目:hdoj 3605 Escape 分类:中等最大流 | 二分图多重匹配 题意:给出n个人和m个星球,每个人有想去的兴趣,然后每个星球有容量,问能不能让所有人都住在自己想去的星球? 分析:最大流的话卡的非常严,这个题目写了之后手写MTL,超内存,然后加入状态压缩之后TEL,后面没办法了看别人说C++提交能过,改C++Compilation Error,不容易呀,原来C++用的vc编译器,果然改了之后600ms过了. 首先题意很明显,建图方法也很明显,要设一个超级远点s和汇点t,其他的不说了.

HDU 5352——MZL&#39;s City——————【二分图多重匹配、拆点】

MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 710    Accepted Submission(s): 245 Problem Description MZL is an active girl who has her own country. Her big country has N cities numb

HDU 1669 二分图多重匹配+二分

Jamie's Contact Groups Time Limit: 15000/7000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 747    Accepted Submission(s): 303 Problem Description Jamie is a very popular girl and has quite a lot of friends, so she

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加