题目描述
给出\(n\)个人,\(m\)个星球,每个星球有一个移民人数限制\(lim\),现在询问你一个最好的匹配方式,使移民人数最多。
\(n\) (1 \(\le\) \(n\) \(\le\) 100000), \(m\) (1 \(\le\) \(m\) \(\le\) 10)
虽然说是多重匹配,但这里只有星球是1\(\le\)\(lim\)且\(m\)比较小
\(m\)和\(n\)都很大或都有限制时还是会用最大流
样例输入
1 1
1
1
2 2
1 0
1 0
1 1
样例输出
YES
NO
Code
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100002;
int n,m,match[12][N],sz[N],mp[N][12],a[12];
bool vis[12];
int dfs(int s)
{
for(int i=0;i<m;i++)
{
if(mp[s][i] && !vis[i])
{
vis[i]=true;
if(sz[i]<a[i])
{
match[i][sz[i]++]=s;
return 1;
}
for(int j=0;j<sz[i];j++)
{
if(dfs(match[i][j]))
{
match[i][j]=s;
return 1;
}
}
}
}
return 0;
}
int main(){
// freopen("t.in","r",stdin);
while(scanf("%d %d",&n,&m)==2){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&mp[i][j]);
for(int i=0;i<m;i++)
scanf("%d",&a[i]);
memset(sz,0,sizeof(sz));
bool flag=true;
for(int i=0;i<n;i++)
{
memset(vis,false,sizeof(vis));
if(!dfs(i))
{
flag=false;
break;
}
}
if(flag) puts("YES");
else puts("NO");
// for(int i=0;i<m;++i)printf("%d ",sz[i]); puts("");
}
return 0;
}