poj 3281(最大流)
生活随笔
收集整理的這篇文章主要介紹了
poj 3281(最大流)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
解題思路:
這是道匹配的問題,最近剛學網絡流,所以想用網絡流去做。。按照題目要求,我開始建立的是food----cow----drink的圖,源點與所有的food的編號連接,所有的drink的編號與匯點連接,這里所有的有向邊的容量都為1,。。但很不幸的是WA了。??戳藙e人的思路,我才知道原來這里保證不了一頭牛只能吃一份食物和飲料。。把牛分成兩份,相同的牛之間建立一條容量為1的邊,這樣就保證一頭牛只能有1的流量經過,這樣就能夠使得每頭牛吃一份啦。。。這道題目確實很巧妙,是道好題。。
AC:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define inf 1000 #define nMax 410 #define Max(a,b) (a>b?a:b) #define Min(a,b) (a<b?a:b)int map[nMax][nMax]; int N,F,D; int path[nMax]; int queue[nMax * 100]; int head,end; //bool flag[nMax]; //廣搜求一條增廣路 int bfs() {int minFlow = inf,u;memset(path, -1, sizeof(path));head = 0;end = 1;queue[head] = 0;while (head < end){u = queue[head ++];if (u == 2 * N + F + D + 1){break;}for (int i = 1; i <= 2 * N + F + D + 1; ++ i){if (path[i] == -1 && map[u][i] ){if (minFlow > map[u][i]){minFlow = map[u][i];}queue[end ++] = i;path[i] = u;}}}if (path[2 * N + F + D + 1] == -1){return -1;}return minFlow; } //EK算法,每次廣搜得到一條增廣路徑,然后更新殘留網絡 void Edmods_Karp() {int flow, maxFlow = 0, now, pre;while ((flow = bfs()) != -1){maxFlow += flow;now = 2 * N + F + D + 1;while (now != 0){pre = path[now];map[pre][now] -= flow;map[now][pre] += flow;now = pre;}}printf("%d\n", maxFlow); } //按照源點-食物-牛-牛-飲料-匯點的順序建圖 void buildMap() {int fNum,dNum,fd;while (scanf("%d %d %d", &N, &F, &D) != EOF){memset(map, 0, sizeof(map));//memset(flag, false, sizeof(flag));for (int i = 1; i <= N; ++ i){scanf("%d %d", &fNum, &dNum);for (int j = 0; j < fNum; ++ j){scanf("%d", &fd);map[0][fd] = 1;map[fd][i + F] = 1;}map[i + F][i + F + N] = 1;for (int j = 0; j < dNum; ++ j){scanf("%d", &fd);map[fd + 2 * N + F][F + 2 * N + D + 1] = 1;map[i + F + N][fd + 2 * N + F] = 1;}}Edmods_Karp();} } //注意這里給點編號,0-源點,1-F是食物,F+1-F+N是牛左點,F+N+1-F+N+N是牛右點,F+N+N+1-F+N+N+D是drink飲料點,F+N+N+D+1是匯點int main() {buildMap();return 0; }
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的poj 3281(最大流)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 3081(并查集+最大流)
- 下一篇: hdu 3572(最大流)