Problem I. Magic Potion
There are n heroes and m monsters living in an island. The monsters became very vicious these days, so the heroes decided to diminish the monsters in the island. However, the i-th hero can only kill one monster belonging to the set Mi . Joe, the strategist, has k bottles of magic potion, each of which can buff one hero’s power and let him be able to kill one more monster. Since the potion is very powerful, a hero can only take at most one bottle of potion.
Please help Joe find out the maximum number of monsters that can be killed by the heroes if he uses the optimal strategy.
Input
The first line contains three integers n, m, k (1 ≤ n, m, k ≤ 500) — the number of heroes, the number of monsters and the number of bottles of potion.
Each of the next n lines contains one integer ti , the size of Mi , and the following ti integers Mi,j (1 ≤ j ≤ ti), the indices (1-based) of monsters that can be killed by the i-th hero (1 ≤ ti ≤ m, 1 ≤ Mi,j ≤ m).
Output
Print the maximum number of monsters that can be killed by the heroes.
题意
有n个英雄,m个怪,一个英雄最多杀一个怪,但有k次机会可以让一个英雄多杀一个怪,但一个英雄最多也只能杀两个。
思路
首先我想到了二分图最大匹配(匈牙利算法),如果没有k那就是二分图匹配的模板题,多了个k就是网络最大流的板子题。但我觉得二分图最大匹配也能写,就稍微改变了匈牙利算法,最后也AC了。
二分图最大匹配的思路就是将所有英雄都复制一遍,这样就有2n个英雄,前n个英雄和后n个英雄是完全一样的。因为每个英雄都可以杀一个怪,所以前n个就直接跑最大,后n个是因为有额外k次机会,所以击杀上限为k。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+10;
int n,m,k,a[1005][505],b[505],girl[505];
bool find(int x){ //给英雄x匹配怪物
int i,j;
for (j=1;j<=m;j++)
{
if (a[x][j]==1 && b[j]==0) //如果可以匹配,并且没有被标记
{
b[j]=1;
if (girl[j]==0 || find(girl[j])) {
girl[j]=x;
return true;
}
}
}
return false;
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++) //输入并复制英雄
{
int s,x;
cin>>s;
for(int j=1;j<=s;j++)
{
scanf("%d",&x);
a[i][x]=1;
a[n+i][x]=1;
}
}
int sum=0,sum1=0;
for (int i=1;i<=2*n;i++) //给每个英雄找匹配的怪
{
memset(b,0,sizeof(b)); //清除标记
if (find(i)) //如果匹配到了
{
if(i<=n)
sum++;
else
sum1++;
}
}
cout<<sum+min(sum1,k)<<endl;
return 0;
}