[二分图匹配] gym101981 I

题意

n个英雄,m个怪兽,某个英雄可以杀死某些编号的怪兽,但他只能杀死这些怪兽中的一只;有k瓶药水,某个英雄喝了可以多杀一只怪兽,但是最多喝一瓶;给出第i个英雄可以杀的怪兽编号,问总共最多杀几只怪兽。

思路

连续做两次二分图匹配。做第一次匹配后不需要处理已经匹配过的边,因为有多种匹配方式,每种匹配方式对第二次匹配得到的结果可能不一样,做一次二分图匹配只能得到最大匹配数。连着做二分图匹配可以保证第一次加第二次最优。

#include<set>
#include<map>
#include<stack>
#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
const int maxn = 1e3+5;
int n, m, k;
int g[maxn][maxn], p[maxn];
bool vis[maxn];

bool dfs(int u){
	for(int i = 1; i <= m; i++){
		if(g[u][i] && !vis[i]){
			vis[i] = 1;
			if(p[i] == 0 || dfs(p[i])){
				p[i] = u;
				return 1;
			}
		}
	}
	return 0;
}

int main(){
	scanf("%d %d %d", &n, &m, &k);
	int u, v;
	for(int i = 1; i <= n; i++){
		scanf("%d", &u);
		for(int j = 1; j <= u; j++){
			scanf("%d", &v);
			g[i][v] = 1;
		}
	}
	int ans = 0;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++) vis[j] = 0;
		if(dfs(i)) ans++;
	}
	int cnt = 0;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++) vis[j] = 0;
		if(dfs(i)) cnt++;
	}
	ans += min(cnt, k);
	printf("%d\n", ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值