poj3281--网络流 + 拆点

来源:互联网 发布:数据绑定 编辑:程序博客网 时间:2024/04/30 03:33

可怜好久没有给自己的博客添加博文了。。

poj3281是一道网络流的题目,也是我写的第二道网络流。参考了别人的代码过了委屈

题意:一个农场主要喂养他的牛, 就给它们做了好多好吃好喝的。但是牛很挑剔,每头牛都只吃特定的食物和喝特定的饮料。问农场主最多能满足多少头牛。

解题思路:这就是个网络流的题目,关键是构图。重点在于将牛分成两个点存。最开始我也不是很理解,后来就明白了。牛的左半边和右半边中间有一条权为1的边,就保证了一头牛只能享用一份食物和饮料。

源码:

//#define LOCAL#include <stdio.h>#include <string.h>#include <queue>using namespace std; #define MAXN 500#define INF 0x7fffffffint n, f, d;int map[MAXN][MAXN];int flow[MAXN][MAXN];int minflow[MAXN];int pre[MAXN];void getmap(){int i, j;int a, b;int food, drink;memset(map, 0, sizeof(map));for(i = 1; i <= f; i++) // super srcmap[0][i] = 1;for(i = 1; i <= d; i++) // super destmap[f + 2* n + i][f + 2 * n + d + 1] = 1;for(i = 1; i <= n; i++){scanf("%d%d", &a, &b);for(j = 1; j <= a; j++) // food -> cow(left){scanf("%d", &food);map[food][f + i] = 1;}map[f + i][f + n + i] = 1; cow(left) --> cow(right)for(j = 1; j <= b; j++) // cow(right) --> drink{scanf("%d", &drink);map[f + n + i][f + 2 * n + drink] = 1;}}}int maxflow(){int s, t, cur, u, v, ans = 0;s = 0; // src t = f + 2 * n + d + 1; // destmemset(flow, 0, sizeof(flow));while(1){memset(pre, -1, sizeof(pre));memset(minflow, 0, sizeof(minflow));queue<int> q;minflow[s] = INF;q.push(s);while(!q.empty()){cur = q.front();q.pop();if(cur == t)break;for(v = s; v <= t; v++){if(pre[v] < 0 && map[cur][v] > flow[cur][v]){pre[v] = cur;minflow[v] = min(map[cur][v] - flow[cur][v], minflow[cur]);q.push(v);}}}if(pre[t] == -1)break;for(v = t; v != s; v = pre[v]){u = pre[v];flow[u][v] += minflow[v];flow[v][u] -= minflow[v];}ans += minflow[t];}return ans; }int main(){#ifdef LOCALfreopen("poj3281.txt", "r", stdin);// freopen(".txt", “w”, stdin);#endifwhile(scanf("%d%d%d", &n, &f, &d) != EOF){getmap();printf("%d\n", maxflow());}return 0;}
感觉现在我写这种类型的题目思路都比较清晰了,以后自己写的题就会放上详细的题解了,(图文并茂)。