poj 3181 网络流,建图。
2015-07-27 19:57
375 查看
题意:
农夫约翰为他的牛准备了F种食物和D种饮料。
每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。
问最多能有多少头牛可以同时得到喜欢的食物和饮料。
解析:
由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。
如下建图:
s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t
所以分配一下点:
s = 0,
牛1= 1~n,
牛2= n+1 ~ 2*n,
食物= 2*n+1 ~ 2 * n + f,
饮料= 2*n+f+1 ~ 2*n+f+d,
t = 2*n+f + d + 1。
然后按照流量方向建立一张有向图,接着求一个最大流就行了。
好方便。。。
代码:
农夫约翰为他的牛准备了F种食物和D种饮料。
每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。
问最多能有多少头牛可以同时得到喜欢的食物和饮料。
解析:
由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。
如下建图:
s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t
所以分配一下点:
s = 0,
牛1= 1~n,
牛2= n+1 ~ 2*n,
食物= 2*n+1 ~ 2 * n + f,
饮料= 2*n+f+1 ~ 2*n+f+d,
t = 2*n+f + d + 1。
然后按照流量方向建立一张有向图,接着求一个最大流就行了。
好方便。。。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <climits> #include <cassert> #define LL long long #define lson lo, mi, rt << 1 #define rson mi + 1, hi, rt << 1 | 1 using namespace std; const int maxn = 400 + 10;//100牛*2 + 100食 + 100饮 + s + t const int inf = 0x3f3f3f3f; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); int n, f, d; int flow[maxn][maxn]; int cap[maxn][maxn]; int lev[maxn]; int a[maxn]; void addEdge(int fr, int to, int c) { cap[fr][to] += c; } //bfs找层次网络,一次寻找多条增广路径 //st最小顶点编号,ed最大顶点编号,s源点,t汇点 bool bfs(int st, int ed, int s, int t) { memset(lev, inf, sizeof(lev)); queue<int> q; q.push(s); lev[s] = 0; while (!q.empty()) { int t = q.front(); q.pop(); for (int i = st; i <= ed; i++) { if (flow[t][i] < cap[t][i]) { if (lev[t] + 1 < lev[i]) { lev[i] = lev[t] + 1; q.push(i); } } } } return lev[t] < inf; } //利用层次网络进行增广,每次dfs寻找的是从该点出发进行dfs增加的总量 //a表示从源点到该节点可增广流量 int dfs(int v, int st, int ed, int s, int t) { int res = 0; if (v == t) return a[t]; for (int i = st; i <= ed; i++) { if (a[v] == 0) break; if (flow[v][i] < cap[v][i] && lev[v] + 1 == lev[i]) { a[i] = min(a[v], cap[v][i] - flow[v][i]); int temp = dfs(i, st, ed, s, t); res += temp; a[v] -= temp; flow[v][i] += temp; flow[i][v] -= temp; } } if (res == 0) { lev[v] = inf; } return res; } int dinic(int st, int ed, int s, int t) { int res = 0; memset(flow, 0, sizeof(flow)); while (bfs(st, ed, s, t)) { memset(a, inf, sizeof(a)); int temp = dfs(s, st, ed, s, t); if (temp == 0) break; res += temp; } return res; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL while (~scanf("%d%d%d", &n, &f, &d)) { memset(cap, 0, sizeof(cap)); for (int i = 1; i <= n; i++) { int ft, dt; scanf("%d%d", &ft, &dt); while (ft--) { int x; scanf("%d", &x); addEdge(2 * n + x, i, 1); } while (dt--) { int x; scanf("%d", &x); addEdge(i + n, 2 * n + f + x, 1); } } int s = 0, t = 2 * n + f + d + 1; for (int i = 2 * n + 1; i <= 2 * n + f; i++) { addEdge(s, i, 1); } for (int i = 2 * n + f + 1; i <= 2 * n + f + d; i++) { addEdge(i, t, 1); } for (int i = 1; i <= n; i++) { addEdge(i, i + n, 1); } printf("%d\n", dinic(s, t, s, t)); } return 0; }
相关文章推荐
- 【HTTP】简单的HTTP下载网页流程(HTTPClient4.3)
- http格式
- TCP协议中的三次握手和四次挥手
- 关于流量有上下界的网络流问题的求解
- CHttpFile POST 时 Cookie 疑问
- http协议
- Android之ListView异步加载网络图片(优化缓存机制)
- http服务区域组网的一种方法
- Android使用HttpClient向服务器传输文件
- 网络爬虫heritrix 3.1 在Windows上的搭建与使用方法说明
- httpwebreqeust读取httponly的cookie
- poj 1459 多源汇网络流 ISAP
- android下载网络图片并缓存
- 标准Http协议支持六种请求方法
- POJ2391 Ombrophobic Bovines 网络流拆点+二分+floyed
- TCP/IP
- Tcp(keepalive)保活机制
- 在线HTTP POST/GET接口测试工具 - aTool在线工具
- hdu 4004 二分 2011大连赛区网络赛D
- hdu 4002 欧拉函数 2011大连赛区网络赛B