POJ1149 PIGS(最大流)
生活随笔
收集整理的這篇文章主要介紹了
POJ1149 PIGS(最大流)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:
? ? ? 有一個人,他有m個豬圈,每個豬圈里面有一定數(shù)量的豬,但是每個豬圈的門都是鎖著的,他自己沒有鑰匙,只有顧客有鑰匙,一天依次來了n個顧客,(記住是依次來的)他們每個人都有一些鑰匙,和他們想買豬的數(shù)量,他們可以用自己的鑰匙打開豬圈,最后賣給他多少是你自己決定的,當顧客打開它能打開的這幾個豬圈的時候你可以調(diào)整打開的這幾個豬圈里面的豬的數(shù)量,等他走了,豬圈又被鎖上了,就這樣,最后問你最多能賣給這n個人多少頭豬。
思路:
? ? ? 最大流,建圖挺簡單的(很早以前我做過這個題目,當時寫的很麻煩,哎!記得那天我在不停的修改又難看又笨拙的代碼,那是我逝去的青春...哈哈不扯了,繼續(xù)),我的做法是先開一個數(shù)組hash[],hash[i]表示的是當前豬圈對應的虛擬的點是那個點,一會在解釋虛擬的點的問題,然后我們虛擬出來兩個點,原點s,和匯點t
然后:
(1) s 向所有的顧客連接一條邊 流量是顧客要買的豬的數(shù)量
(2) 所有的豬圈向t連接一條邊,流量是豬圈的豬的數(shù)量
? ? ? 有一個人,他有m個豬圈,每個豬圈里面有一定數(shù)量的豬,但是每個豬圈的門都是鎖著的,他自己沒有鑰匙,只有顧客有鑰匙,一天依次來了n個顧客,(記住是依次來的)他們每個人都有一些鑰匙,和他們想買豬的數(shù)量,他們可以用自己的鑰匙打開豬圈,最后賣給他多少是你自己決定的,當顧客打開它能打開的這幾個豬圈的時候你可以調(diào)整打開的這幾個豬圈里面的豬的數(shù)量,等他走了,豬圈又被鎖上了,就這樣,最后問你最多能賣給這n個人多少頭豬。
思路:
? ? ? 最大流,建圖挺簡單的(很早以前我做過這個題目,當時寫的很麻煩,哎!記得那天我在不停的修改又難看又笨拙的代碼,那是我逝去的青春...哈哈不扯了,繼續(xù)),我的做法是先開一個數(shù)組hash[],hash[i]表示的是當前豬圈對應的虛擬的點是那個點,一會在解釋虛擬的點的問題,然后我們虛擬出來兩個點,原點s,和匯點t
然后:
(1) s 向所有的顧客連接一條邊 流量是顧客要買的豬的數(shù)量
(2) 所有的豬圈向t連接一條邊,流量是豬圈的豬的數(shù)量
(3) 對于每一個顧客,我們首先虛擬出來一個點,然后把這個顧客所有連接的點都指向這個 ? ?虛擬的點,比如當 ? ? ?前的這個顧客有三把鑰匙1,2,3,因為這三個豬圈可以直接調(diào)整數(shù)量 ? ?了,所以我們可以讓虛擬出來的這個點 ? ? ? a代替當前這步的三個點,1->a ,2->a ,3->a,然 ? ?后在更新上面說的那個hash[],hash[1] = a ,hash[2] = a ? ? ? ? ? ? ? ?,hash[3] = a,以后只要是 ? ?訪問1,2,3中的任何一個,直接訪問a,就行了,然后在建立一條當前顧客到新虛擬 ? ? ?出來 ? ? 的這個點的邊,流量INF。
ok,就是以上那些,要是不明白可以自己按照上面的見圖思路畫個圖,很容易理解。
#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(最大流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对最大团的理解
- 下一篇: poj2112 二分最大流+Floyd