1. 程式人生 > >POJ 1149 PIGS 建圖,最大流

POJ 1149 PIGS 建圖,最大流

col 表示 ems span 相同 scanf 分享 dinic pan

題意:

你m個豬圈以及每個豬圈裏原來有多少頭豬,先後給你n個人,每個人能打開某一些豬圈並且他們最多想買Ki頭豬,在每一個人買完後能將打開的豬圈中的豬順意分配在這次打開豬圈裏,在下一個人來之前 已打開的豬圈會被鎖上。
問最多能賣幾頭豬

分析:

  這個題明著想呢,肯定是要建N排點的,表示相同的豬圈的點連inf邊,跑最大流的。

  建那麽多點肯定是會炸的。

  在網絡流中呢,如果我們做題的初步思路是最大流,那麽肯定要將題目中問的直接問題抽象成水流,比如這道題,問最多的賣豬數,我們當然就要把豬的數量作為“流”,這是大家心照不宣的。

  所謂建圖呢?個人認為,網絡流最終要的是“限制”二字,網絡流的流量和連邊就是一個個限制問題,所以我們要參透題目中給的限制問題,有時並不必要把圖中的每一個關系都建邊。

  像這個題目中,豬圈裏豬的數量是限制,每個人能打開的豬圈也是限制,買家的先後順序也是限制,買豬的數量也是限制。所以我們只需要用這些限制構建模型,開始:

  源點到每個豬圈來買的第一個人連一條容量為該豬圈裏豬的數量的邊(這個滿足了第一、二個限制)

  對於每個豬圈,第i個來買的人向第i+1個來買的人連一條容量為正無窮的邊(這個滿足了第三個限制)

  每個人向匯點連一條容量為購買數量的邊(這個滿足了第四個限制)

  網絡流就是這樣,嚴密合理得像一個故事一樣。

  一頭豬,從豬圈出來經過幾人之手最終被某個人買走,完成了他的使命。一單位流量從原點,流經一些人,最終流向匯點,也完成了它的使命。這邊是對網絡流的感性理解。

代碼:

技術分享圖片
 1 #include<algorithm>
 2 #include<iostream> 
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<cmath>
 7 #define ms(a,x) memset(a,x,sizeof(a))
 8 using namespace std;
 9 const int N=105,M=1005,inf=1e9;
10 struct node{int y,z,nxt;}e[N*M*2];
11 int n,m,S,T,pg[M],nw[M],c=1; 12 int q[N],h[N],d[N],vis[N]; 13 void add(int x,int y,int z){ 14 e[++c]=(node){y,z,h[x]};h[x]=c; 15 e[++c]=(node){x,0,h[y]};h[y]=c; 16 } bool bfs(){ 17 int f=0,t=0;ms(d,-1); 18 q[t++]=S;d[S]=0; 19 while(f<t){ 20 int x=q[f++]; 21 for(int i=h[x],y;i;i=e[i].nxt) 22 if(d[y=e[i].y]==-1&&e[i].z) 23 d[y]=d[x]+1,q[t++]=y; 24 } return (d[T]!=-1); 25 } int dfs(int x,int f){ 26 if(x==T) return f;int w,tmp=0; 27 for(int i=h[x],y;i;i=e[i].nxt) 28 if(d[y=e[i].y]==d[x]+1&&e[i].z){ 29 w=dfs(y,min(f-tmp,e[i].z)); 30 if(!w) d[y]=-1; 31 e[i].z-=w;e[i^1].z+=w; 32 tmp+=w;if(tmp==f) return f; 33 } return tmp; 34 } int dinic(){ 35 int tot=0; 36 while(bfs()) tot+=dfs(S,inf); 37 return tot; 38 } int main(){ 39 scanf("%d%d",&m,&n);S=0;T=n+1; 40 for(int i=1;i<=m;i++) 41 scanf("%d",&pg[i]); 42 for(int i=1;i<=n;i++){ 43 int a,b,x;scanf("%d",&a); 44 while(a--){ 45 scanf("%d",&x); 46 if(!nw[x]) add(S,i,pg[x]),nw[x]=i; 47 else add(nw[x],i,inf),nw[x]=i; 48 } scanf("%d",&b);add(i,T,b); 49 } printf("%d",dinic()); 50 return 0; 51 }
最大流

POJ 1149 PIGS 建圖,最大流