POJ - 3281 Dining

1.题面

http://poj.org/problem?id=3281

2.题意

已知牛的数量n,饮料的种类d,食物的种类,以及每头牛喜欢的食物和饮料,希望你求出最合理的搭配,使最终能吃到饭的牛的数量最多

3.思路

网络流最大流,思路很简单,不说了

4.代码


/*****************************************************************
    > File Name: cpp_acm.cpp
    > Author: Uncle_Sugar
    > Mail: uncle_sugar@qq.com
    > Created Time: Mon 03 Oct 2016 19:01:17 CST
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;

# define rep(i,a,b) for (i=a;i<=b;i++)
# define rrep(i,a,b) for (i=b;i>=a;i--)
# define mset(aim, val) memset(aim, val, sizeof(aim))

struct QuickIO{
	QuickIO(){const int SZ = 1<<20;
		setvbuf(stdin ,new char[SZ],_IOFBF,SZ);
		setvbuf(stdout,new char[SZ],_IOFBF,SZ);
	}				//*From programcaicai*//
}QIO;

template<class T>void PrintArray(T* first,T* last,char delim=' '){
    for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim);
}

/*
1.see the size of the input data before you select your algorithm 
2.cin&cout is not recommended in ACM/ICPC
3.pay attention to the size you defined, for instance the size of edge is double the size of vertex
*/

const int debug = 1;
//# const int size  = 10 + ; 
const int INF = INT_MAX>>1;
typedef long long ll;

const int MAXN = 510;
const int MAXM = MAXN*MAXN;


struct Edge{
	int to, f, nxt;
}edge[MAXM];
int tot = 0;

int head[MAXN];

void init(){
	tot = 0;
	memset(head, -1, sizeof(head));
}


void addedge(int from, int to, int f){
	edge[tot].to = to;edge[tot].f = f;
	edge[tot].nxt = head[from]; head[from] = tot++;

	edge[tot].to = from;edge[tot].f = 0;
	edge[tot].nxt = head[to]; head[to] = tot++;
}

int level[MAXN];
bool bfs(int s, int t){
	static queue<int> que;
	while (!que.empty()) que.pop();
	memset(level, 0, sizeof(level));
	que.push(s); level[s] = 1;
	while (!que.empty()){
		int cur = que.front();	que.pop();
		if (cur == t) return true;
		for (int e = head[cur]; ~e; e = edge[e].nxt){
			int to = edge[e].to, f = edge[e].f;
			if (!level[to] && f){
				level[to] = level[cur] + 1;
				que.push(to);
			}
		}

	}
	return false;
}

int dfs(int u, int t, int sup){
	if (u == t) return sup;
	int ret = 0;
	for (int e = head[u]; ~e; e = edge[e].nxt){
		int cur = edge[e].to, f = edge[e].f;
		if (level[cur] == level[u] + 1 && f){
			int mi = min(sup - ret, f);
			int tf = dfs(cur, t, mi);
			edge[e].f -= tf; edge[e^1].f += tf;
			ret += tf;
		}
		if (ret == sup) return ret;
	}
	return ret;
}

int Dinic(int s, int t){
	int ret = 0;
	while (bfs(s, t))  ret += dfs(s, t, INF);
	return ret;
}


int main()
{
	/*std::ios::sync_with_stdio(false);cin.tie(0);*/
	int n, f, d;
	while (~scanf("%d%d%d", &n, &f, &d)){
		init();
		int s = 0, t = f + n + n + d + 1;
		for (int i = 1; i <= f; i++) addedge(s, i, 1); 
		for (int i = 1; i <= n; i++) addedge(f + i, f + n + i, 1);
		for (int i = 1; i <= d; i++) addedge(f + n + n + i, t, 1);

		for (int i = 1; i <= n; i++){
			int a, b, tmp;
			scanf("%d%d", &a, &b);
			while (a--){
				scanf("%d", &tmp);
				addedge(tmp, f + i, 1);
			}
			while (b--){
				scanf("%d", &tmp);
				addedge(f + n + i, f + n + n + tmp, 1);
			}
		}
		int ans = Dinic(s, t);
		printf("%d\n", ans);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值