Escape
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 11950 Accepted Submission(s): 2919
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
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.
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
问题描述
2012如果这是世界末日该怎么办?我不知道怎么。但是现在科学家们已经发现有些恒星可以生存,但有些人不适合生活在这个星球上。现在科学家需要你的帮助,是要确定所有人能够在这些行星中生活。
输入
更多的测试数据集,每个数据的开始是n(1 <= n <= 100000),m(1 <= m <= 10)n表示地球上有n个人,m代表行星,行星和人标签是从0开始的。这里有n行,每行代表一个合适的人的生活条件,每行有m位,第i位数是1,表示一个人适合生活在第i行星,或者是0这个人不适合生活在第i个星球上。
最后一行有m位,第i位数字表示第i行星最多可以包含ai人。
0 <= ai <= 100000
输出
确定是否所有人都能生活在这些星球
如果可以输出YES,否则输出NO。
第一次了解到多重匹配,但是搜题解为什么好多人用网络流,最大流写呢,还都是140、150多行的代码。。。大概因为写起来爽吧!刚了解多重匹配,还得在了解网络流,有点无奈。
多重匹配和二分图的最大匹配很相似的,稍作加工,思想都一样。函数dfs()中就是核心代码。
可以当多重分配的模板了,比较好,连输入都函数化了,以后可以多多尝试这种代码风格。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int mat[15][100005];//保存我们安排的匹配,数组的行列刚好与p数组相反
int vnum[15];//vnum[i]:i当前已匹配的人数
int p[100005][15];//原始关系匹配图,谁可以和谁匹配;p[i][j]:i可以与j匹配,可以看出是一对多的
int vis[15];//标记
int w[15];//w[i]:i最多匹配的人数
void input()//输入
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&p[i][j]);//每个人可以匹配的行星
}
}
for(int i=0;i<m;i++)
scanf("%d",&w[i]);//每个行星最多容纳的人数
return;
}
int dfs(int v)
{
for(int i=0;i<m;i++)
{
if(p[v][i]&&!vis[i])
{
vis[i]=1;
if(vnum[i]<w[i])//当前行星容纳的人数小于最大值,还可以匹配
{
mat[i][vnum[i]++]=v;//第vum[i]++个是v
return 1;
}
else
{
for(int j=0;j<vnum[i];j++)//否则让别人去另一个行星
{
if(dfs(mat[i][j]))
{
mat[i][j]=v;
return 1;
}
}
}
}
}
return 0;
}
void judge()
{
for(int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
if(!dfs(i))//有人不能被匹配到行星
{
printf("NO\n");
return;
}
}
printf("YES\n");
return;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
input();
memset(vnum,0,sizeof(vnum));
judge();
}
return 0;
}