题面
https://vjudge.net/problem/Gym-101981I
题意
岛上有m个怪兽,n个勇士,每个勇士只能消灭特定的一些怪兽,而且每个勇士只能消灭一只怪兽,但有k瓶药水,可以让一个勇士可以多打一只怪兽,但是每个勇士只能喝一瓶,问最大能打死几只怪兽
网络流思路
我们只需要建一个如下图然后跑一个最大流就可以得到答案了
网络流代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<double,double> Pdd;
const int mod=1e9+7;
const int maxn=6000;
const int maxe=1e5+10;
const int inf=0x3f3f3f3f;
struct Edge
{
int to,val,nxt;
}e[400050];
int n,m,k;
int cnt=0;
int head[maxn],cur[maxn];
int deep[maxn];
int S,T;
void init()
{
cnt=0;
memset(head,-1,sizeof(head));
}
void add_edge(int from,int to,int val)
{
e[cnt].to=to;
e[cnt].val=val;
e[cnt].nxt=head[from];
head[from]=cnt++;
e[cnt].to=from;
e[cnt].val=0;
e[cnt].nxt=head[to];
head[to]=cnt++;
}
int dfs(int from,int flow)
{
if(from==T) return flow;
for(int &i=cur[from];i!=-1;i=e[i].nxt)
{
if(deep[e[i].to]==deep[from]+1&&e[i].val!=0)
{
int d=dfs(e[i].to,min(flow,e[i].val));
if(d>0)
{
e[i].val-=d;
e[i^1].val+=d;
return d;
}
}
}
return 0;
}
int bfs()
{
queue<int> que;
while(!que.empty()) que.pop();
memset(deep,0,sizeof(deep));
deep[S]=1;
que.push(S);
do
{
int from=que.front();que.pop();
for(int i=head[from];i!=-1;i=e[i].nxt)
{
//printf("from = %d ,to = %d\n",from,e[i].to);
if(deep[e[i].to]==0&&e[i].val>0)
{
deep[e[i].to]=deep[from]+1;
que.push(e[i].to);
if(e[i].to==T) return 1;
}
}
}while(!que.empty());
if(deep[T]>0) return 1;
else return 0;
}
int Dicnic()
{
int ans=0;
while(bfs())
{
for(int i=0;i<=T;i++) cur[i]=head[i];
while(int d=dfs(S,inf))
{
ans+=d;
}
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
init();
S=0;T=n+m+2;
for(int i=1,k,x;i<=n;i++)
{
scanf("%d",&k);
for(int j=0;j<k;j++)
{
scanf("%d",&x);
add_edge(i,x+n,1);
}
}
for(int i=1;i<=n;i++)
add_edge(S,i,1);
for(int i=1;i<=m;i++)
add_edge(n+i,T,1);
add_edge(S,n+m+1,k);
for(int i=1;i<=n;i++)
add_edge(n+m+1,i,1);
printf("%d\n",Dicnic());
return 0;
}
二分图
欠着欠着