日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

有上下界的网络流1-无源汇带上下界网络流SGU194

發布時間:2024/10/12 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 有上下界的网络流1-无源汇带上下界网络流SGU194 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有上下界的網絡流1-無源匯帶上下界網絡流SGU194

今天開始啃網絡流了。對于求解無源匯帶上下界的網絡流,我們可以這樣建圖:
建圖模型:?
????????以前寫的最大流默認的下界為0,而這里的下界卻不為0,所以我們要進行再構造讓每條邊的下界為0,這樣做是為了方便處理。對于每根管子有一個上界容量up和一個下界容量low,我們讓這根管子的容量下界變為0,上界為up-low。可是這樣做了的話流量就不守恒了,為了再次滿足流量守恒,即每個節點"入流=出流”,我們增設一個超級源點st和一個超級終點sd。我們開設一個數組du[]來記錄每個節點的流量情況。

du[i]=in[i](i節點所有入流下界之和)-out[i](i節點所有出流下界之和)。

當du[i]大于0的時候,st到i連一條流量為du[i]的邊。

當du[i]小于0的時候,i到sd連一條流量為-du[i]的邊。

最后對(st,sd)求一次最大流即可,當所有附加邊全部滿流時,有可行解。
(我們默認了圖中每條邊已經有了最小的流量,可是現在的圖中的點 入流不等于出流,于是我們通過附加邊使得:
?????? 1. 超級源點 連接到 入流大于出流的點,以增大該點的出流,使實際流量平衡(實際流量為最小流量+當前流量,并且不算超級源點和匯點的流量)。
?????? 2.出流大于入流的點 連接到 超級匯點,以增大該點的入流(因為該點可以把流量全部排到超級匯點,所以可以有跟多的流量流入該點),使實際流量平衡。

注意:無源匯帶上下界的網絡流中 求出來的網絡流是個循環體,即雖然沒有源點匯點但內部的點都保持流量守恒。
??????????? 且該算法僅能求出一個可行解,最終得到的網絡流并不能保證是最大流。


SGU194題目大意:
給n個點,及m根pipe,每根pipe用來流躺液體的,單向的,每時每刻每根pipe流進來的物質要等于流出去的物質,要使得m條pipe組成一個循環體,里面流躺物質。并且滿足每根pipe一定的流量限制,范圍為[Li,Ri].即要滿足每時刻流進來的不能超過Ri(最大流問題),同時最小不能低于Li。
今晚RP不錯,一遍就AC。
下面是我的代碼:

1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #include<cstring> 8 #define maxn 0x7fffffff 9 using namespace std; 10 struct edge{int to,cap,rev,num;}; 11 int flow[100000],ch[250],du[250]; 12 vector <edge> E[250]; 13 int st,sd,n,m; 14 void Add_Edge(int from,int to,int cap,int num){ 15 edge t;t.num=num*2; 16 t.to=to,t.cap=cap,t.rev=E[to].size(); 17 E[from].push_back(t); 18 t.num=num*2+1; 19 t.to=from,t.cap=0,t.rev=E[from].size()-1; 20 E[to].push_back(t); 21 } 22 bool bfs(){ 23 queue <int> que; 24 memset(ch,-1,sizeof(ch)); 25 ch[st]=0;que.push(st); 26 while(que.size()){ 27 int t=que.front();que.pop(); 28 for(int i=0;i<E[t].size();i++){ 29 if(E[t][i].cap && ch[E[t][i].to]<0) { 30 ch[E[t][i].to]=ch[t] + 1; 31 que.push(E[t][i].to); 32 } 33 } 34 } 35 return (ch[sd]>-1); 36 } 37 int dfs(int v,int f){ 38 int r=0; 39 if(v==sd) return f; 40 for(int i=0;i<E[v].size();i++){ 41 if(f==0) return r; 42 edge &t=E[v][i]; 43 if(ch[t.to]==ch[v]+1 && t.cap>0) { 44 int u=dfs(t.to,min(t.cap,f)); 45 t.cap-=u;E[t.to][t.rev].cap+=u; 46 f-=u;r+=u; 47 } 48 } 49 return r; 50 } 51 int dinic(){ 52 int flow_sum=0; 53 while(bfs()) flow_sum+=dfs(st,maxn); 54 return flow_sum; 55 } 56 57 int main(){ 58 int a,b,maxx,minn; 59 scanf("%d%d",&n,&m); 60 for(int i=0;i<m;i++){ 61 scanf("%d%d%d%d",&a,&b,&minn,&maxx); 62 flow[i+1]=minn; 63 du[a]-=minn;du[b]+=minn; 64 Add_Edge(a,b,maxx-minn,i+1); 65 } 66 st=0;sd=n+1; 67 for(int i=1;i<=n;i++){ 68 if(du[i]>0) Add_Edge(st,i,du[i],0); 69 if(du[i]<0) Add_Edge(i,sd,-du[i],0); 70 } 71 dinic(); 72 bool flag=true; 73 for(int i=st;i<=sd;i++){ 74 for(int j=0;j<E[i].size();j++){ 75 int k=E[i][j].num; 76 if(k%2==1){ 77 k=k/2; 78 if(1<=k && k<=m) flow[k]+=E[i][j].cap; 79 } 80 else{ 81 if(k==0 && E[i][j].cap>0) flag=false; 82 } 83 84 } 85 } 86 if(flag){ 87 printf("YES\n"); 88 for(int i=1;i<=m;i++) printf("%d\n",flow[i]); 89 } 90 else{ 91 printf("NO\n"); 92 } 93 return 0; 94 }

?

posted on 2017-03-16 22:14 學無止境-1980 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/rdzrdz-acm/p/6561935.html

總結

以上是生活随笔為你收集整理的有上下界的网络流1-无源汇带上下界网络流SGU194的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。