Dining POJ - 3281
Posted wtsruvf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dining POJ - 3281相关的知识,希望对你有一定的参考价值。
题意:
f个食物,d杯饮料,每个牛都有想吃的食物和想喝的饮料,但食物和饮料每个只有一份 求最多能满足多少头牛。。。。
解析:
一道简单的无源汇拆点最大流 无源汇的一个最大流,先建立超级源s和超级汇t, 把s和食物连接 权值为食物的数量1 ,饮料和t连接 权值为饮料的数量1, 因为牛只要一个就好,所以牛的结点容量为1 把牛拆成u和u’ 中间权值为1, 牛和喜欢的食物、饮料分别建边 权值为INF和1都行
这道题和hdu4292 很相似 传送门:https://www.cnblogs.com/WTSRUVF/p/9202751.html
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define mem(a,b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 100100, INF = 0x7fffffff; int head[maxn], d[maxn], cur[maxn]; int n, m, s, t, F, D; int cnt; typedef long long LL; struct node{ int u, v, c, next; }Node[maxn*2]; void add_(int u, int v, int c) { Node[cnt].u = u; Node[cnt].v = v; Node[cnt].c = c; Node[cnt].next = head[u]; head[u] = cnt++; } void add(int u, int v, int c) { add_(u, v, c); add_(v, u, 0); } bool bfs() { queue<int> Q; mem(d, 0); Q.push(s); d[s] = 1; while(!Q.empty()) { int u = Q.front(); Q.pop(); for(int i=head[u]; i!=-1; i=Node[i].next) { node e = Node[i]; if(!d[e.v] && e.c > 0) { d[e.v] = d[e.u] + 1; Q.push(e.v); // cout<< e.v << " " << t <<endl; if(e.v == t) return 1; } } } return d[t] != 0; } int dfs(int u, int cap) { if(u == t || cap == 0) return cap; int ret = 0; for(int &i=cur[u]; i!=-1; i=Node[i].next) { node e = Node[i]; if(d[e.v] == d[e.u] + 1 && e.c > 0) { int V = dfs(e.v, min(cap, e.c)); Node[i].c -= V; Node[i^1].c += V; cap -= V; ret += V; if(cap == 0) break; } } return ret; } int dinic() { int ans = 0; while(bfs()) { // cout<< 2111 <<endl; memcpy(cur, head, sizeof(head)); ans += dfs(s, INF); // cout<< ans <<endl; } return ans; } int main() { cnt = 0; mem(head, -1); cin>> n >> F >> D; s = 0, t = F + D + n + n + 1; for(int i=1; i<=F; i++) add(s, i, 1); for(int i=1; i<=D; i++) add(F+i, t, 1); for(int i=1; i<=n; i++) add(F+D+i, F+D+n+i, 1); for(int i=1; i<=n; i++) { int r, l; cin>> r >> l; for(int j=0; j<r; j++) { int u; cin>> u; add(u, F+D+i, INF); } for(int j=1; j<=l; j++) { int v; cin>> v; add(F+D+n+i, F+v, INF); } } cout<< dinic() <<endl; return 0; }
以上是关于Dining POJ - 3281的主要内容,如果未能解决你的问题,请参考以下文章