POJ1149 PIGS(最大流)
生活随笔
收集整理的這篇文章主要介紹了
POJ1149 PIGS(最大流)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:
? ? ? 有一個(gè)人,他有m個(gè)豬圈,每個(gè)豬圈里面有一定數(shù)量的豬,但是每個(gè)豬圈的門都是鎖著的,他自己沒(méi)有鑰匙,只有顧客有鑰匙,一天依次來(lái)了n個(gè)顧客,(記住是依次來(lái)的)他們每個(gè)人都有一些鑰匙,和他們想買豬的數(shù)量,他們可以用自己的鑰匙打開(kāi)豬圈,最后賣給他多少是你自己決定的,當(dāng)顧客打開(kāi)它能打開(kāi)的這幾個(gè)豬圈的時(shí)候你可以調(diào)整打開(kāi)的這幾個(gè)豬圈里面的豬的數(shù)量,等他走了,豬圈又被鎖上了,就這樣,最后問(wèn)你最多能賣給這n個(gè)人多少頭豬。
思路:
? ? ? 最大流,建圖挺簡(jiǎn)單的(很早以前我做過(guò)這個(gè)題目,當(dāng)時(shí)寫(xiě)的很麻煩,哎!記得那天我在不停的修改又難看又笨拙的代碼,那是我逝去的青春...哈哈不扯了,繼續(xù)),我的做法是先開(kāi)一個(gè)數(shù)組hash[],hash[i]表示的是當(dāng)前豬圈對(duì)應(yīng)的虛擬的點(diǎn)是那個(gè)點(diǎn),一會(huì)在解釋虛擬的點(diǎn)的問(wèn)題,然后我們虛擬出來(lái)兩個(gè)點(diǎn),原點(diǎn)s,和匯點(diǎn)t
然后:
(1) s 向所有的顧客連接一條邊 流量是顧客要買的豬的數(shù)量
(2) 所有的豬圈向t連接一條邊,流量是豬圈的豬的數(shù)量
? ? ? 有一個(gè)人,他有m個(gè)豬圈,每個(gè)豬圈里面有一定數(shù)量的豬,但是每個(gè)豬圈的門都是鎖著的,他自己沒(méi)有鑰匙,只有顧客有鑰匙,一天依次來(lái)了n個(gè)顧客,(記住是依次來(lái)的)他們每個(gè)人都有一些鑰匙,和他們想買豬的數(shù)量,他們可以用自己的鑰匙打開(kāi)豬圈,最后賣給他多少是你自己決定的,當(dāng)顧客打開(kāi)它能打開(kāi)的這幾個(gè)豬圈的時(shí)候你可以調(diào)整打開(kāi)的這幾個(gè)豬圈里面的豬的數(shù)量,等他走了,豬圈又被鎖上了,就這樣,最后問(wèn)你最多能賣給這n個(gè)人多少頭豬。
思路:
? ? ? 最大流,建圖挺簡(jiǎn)單的(很早以前我做過(guò)這個(gè)題目,當(dāng)時(shí)寫(xiě)的很麻煩,哎!記得那天我在不停的修改又難看又笨拙的代碼,那是我逝去的青春...哈哈不扯了,繼續(xù)),我的做法是先開(kāi)一個(gè)數(shù)組hash[],hash[i]表示的是當(dāng)前豬圈對(duì)應(yīng)的虛擬的點(diǎn)是那個(gè)點(diǎn),一會(huì)在解釋虛擬的點(diǎn)的問(wèn)題,然后我們虛擬出來(lái)兩個(gè)點(diǎn),原點(diǎn)s,和匯點(diǎn)t
然后:
(1) s 向所有的顧客連接一條邊 流量是顧客要買的豬的數(shù)量
(2) 所有的豬圈向t連接一條邊,流量是豬圈的豬的數(shù)量
(3) 對(duì)于每一個(gè)顧客,我們首先虛擬出來(lái)一個(gè)點(diǎn),然后把這個(gè)顧客所有連接的點(diǎn)都指向這個(gè) ? ?虛擬的點(diǎn),比如當(dāng) ? ? ?前的這個(gè)顧客有三把鑰匙1,2,3,因?yàn)檫@三個(gè)豬圈可以直接調(diào)整數(shù)量 ? ?了,所以我們可以讓虛擬出來(lái)的這個(gè)點(diǎn) ? ? ? a代替當(dāng)前這步的三個(gè)點(diǎn),1->a ,2->a ,3->a,然 ? ?后在更新上面說(shuō)的那個(gè)hash[],hash[1] = a ,hash[2] = a ? ? ? ? ? ? ? ?,hash[3] = a,以后只要是 ? ?訪問(wèn)1,2,3中的任何一個(gè),直接訪問(wèn)a,就行了,然后在建立一條當(dāng)前顧客到新虛擬 ? ? ?出來(lái) ? ? 的這個(gè)點(diǎn)的邊,流量INF。
ok,就是以上那些,要是不明白可以自己按照上面的見(jiàn)圖思路畫(huà)個(gè)圖,很容易理解。
#include<stdio.h> #include<string.h> #include<queue>#define N_node 5000 #define N_edge 500000 #define INF 1000000000using namespace std;typedef struct {int to ,next ,cost; }STAR;typedef struct {int x ,t; }DEP;STAR E[N_edge]; DEP xin ,tou; int list[N_node] ,listt[N_node] ,tot; int deep[N_node] ,hash[N_node] ,key[N_node];void add(int a ,int b ,int c) {E[++tot].to = b;E[tot].cost = c;E[tot].next = list[a];list[a] = tot;E[++tot].to = a;E[tot].cost = 0;E[tot].next = list[b];list[b] = tot; }int minn(int x ,int y) {return x < y ? x : y; }bool BFS_Deep(int s ,int t ,int n) {memset(deep ,255 ,sizeof(deep));xin.x = s ,xin.t = 0;deep[xin.x] = xin.t;queue<DEP>q;q.push(xin);while(!q.empty()){tou = q.front();q.pop();for(int k = list[tou.x] ;k ;k = E[k].next){xin.x = E[k].to;xin.t = tou.t + 1;if(deep[xin.x] != -1 || !E[k].cost)continue;deep[xin.x] = xin.t;q.push(xin);}}for(int i = 0 ;i <= n ;i ++)listt[i] = list[i];return deep[t] != -1; }int DFS_Flow(int s ,int t ,int flow) {if(s == t) return flow;int nowflow = 0;for(int k = list[s] ;k ;k = E[k].next){listt[s] = k;int to = E[k].to ,c = E[k].cost;if(deep[to] != deep[s] + 1 || !E[k].cost)continue;int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));nowflow += tmp;E[k].cost -= tmp;E[k^1].cost += tmp;if(nowflow == flow) break;}if(!nowflow) deep[s] = 0;return nowflow; }int DINIC(int s ,int t ,int n) {int ans = 0;while(BFS_Deep(s ,t ,n)){ans += DFS_Flow(s ,t ,INF);}return ans; }int main () {int n ,m ,k ,i ,j;int a ,b ,c;while(~scanf("%d %d" ,&m ,&n)){ int s = 0 ,t = n + m + 1 ,now_node = n + m + 1;memset(list ,0 ,sizeof(list)) ,tot = 1;for(i = 1 ;i <= m ;i ++){scanf("%d" ,&a);add(n + i ,t ,a);}for(i = 1 ;i <= N_node ;i ++)hash[i] = i;for(i = 1 ;i <= n ;i ++){scanf("%d" ,&k);now_node ++;for(j = 1 ;j <= k ;j ++){scanf("%d" ,&a);int tmp = a + n;add(now_node ,hash[tmp] ,INF);hash[tmp] = now_node;}scanf("%d" ,&a);add(s ,i ,a);add(i ,now_node ,INF);}printf("%d\n" ,DINIC(s ,t ,now_node));}return 0; }
總結(jié)
以上是生活随笔為你收集整理的POJ1149 PIGS(最大流)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 对最大团的理解
- 下一篇: poj2112 二分最大流+Floyd