//這個題做的蛋疼,,,自己的想法就是不對,歸根結底還是對最大流這種基本的東西不熟悉,,它的內涵都不懂,自己真是水呀
//我第一想的辦法是把regulator[]當做限制,WA,原因沒分析到,這是WA代碼
#include <iostream><br />#include <cstdio><br />#include <queue><br />#include <memory.h></p><p>using namespace std;<br />const int MAX=105,INF=1<<30;<br />int regulator[MAX],m,cap[MAX][MAX],flow[MAX][MAX],<br /> startN,sink,t,a[MAX],n,p[MAX];<br />queue<int> q;<br />int smallest(int i,int j,int k){<br /> int s=i<j?i:j;<br /> return s<k?s:k;<br />}<br />int maxFlow(){<br /> memset(flow,0,sizeof(flow));<br /> int f=0,u;<br /> while(1){<br /> memset(a,0,sizeof(a));//a代表指向結點[v]的增廣路<br /> a[0]=INF;<br /> q.push(0);<br /> //cout<<"s: "<<endl;<br /> while(!q.empty()){<br /> u=q.front(); q.pop();<br /> //cout<<u<<" "<<a[u]<<endl;<br /> for(int v=1;v<=n;v++){<br /> if(!a[v]&&cap[u][v]>flow[u][v]&&<br /> regulator[v]>flow[u][v]){<br /> p[v]=u; q.push(v);<br /> //if(v==1)<br /> // cout<<"ssssssssss: "<<u<br /> // <<" "<<flow[u][v]<<endl;<br /> a[v]=smallest(a[u],cap[u][v]-flow[u][v],<br /> regulator[v]);<br /> //regulator[v]-=a[v];<br /> }<br /> }<br /> }<br /> if(!a[t])<br /> break;<br /> //cout<<a[t]<<endl;<br /> for(u=t;u!=0;u=p[u]){<br /> flow[p[u]][u]+=a[t];//從匯點開始更新正向流<br /> flow[u][p[u]]-=a[t];//從匯點開始更新反向流<br /> //regulator[u]-=a[t];//從匯點開始更新regulator<br /> }<br /> f+=a[t];<br /> }<br /> return f;<br />}<br />int main()<br />{<br /> freopen("i.txt","r",stdin);<br /> int v1,v2,w;<br /> regulator[0]=INF;<br /> while(cin>>n){<br /> memset(cap,0,sizeof(cap));<br /> for(int i=1;i<=n;i++)<br /> cin>>regulator[i];<br /> cin>>m;<br /> for(int i=0;i<m;i++){<br /> cin>>v1>>v2>>w;<br /> cap[v1][v2]=w;<br /> }<br /> cin>>startN>>sink;<br /> //cout<<startN<<" "<<sink<<endl;<br /> for(int i=0;i<startN;i++){<br /> cin>>v1;<br /> //cout<<v1<<endl;<br /> cap[0][v1]=INF;<br /> }</p><p> t=++n;<br /> regulator[t]=INF;<br /> for(int i=0;i<sink;i++){<br /> cin>>v1;<br /> cap[v1][t]=regulator[v1];<br /> }<br /> cout<<maxFlow()<<endl;<br /> }<br /> return 0;<br />}</p><p>
//然後我又想到了一個最佳化 就是兩個點之間的容量cap只能是它u,v,的regulator 和他們邊的cap的最小值,,結果居然水過去了,代碼如下
#include <iostream><br />#include <cstdio><br />#include <queue><br />#include <memory.h></p><p>using namespace std;<br />const int MAX=105,INF=1<<30;<br />int regulator[MAX],m,cap[MAX][MAX],flow[MAX][MAX],<br /> startN,sink,t,a[MAX],n,p[MAX];<br />queue<int> q;<br />int smallest(int i,int j,int k){<br /> int s=i<j?i:j;<br /> return s<k?s:k;<br />}<br />int maxFlow(){<br /> memset(flow,0,sizeof(flow));<br /> int f=0,u;<br /> while(1){<br /> memset(a,0,sizeof(a));//a代表指向結點[v]的增廣路<br /> a[0]=INF;<br /> q.push(0);<br /> while(!q.empty()){<br /> u=q.front(); q.pop();<br /> for(int v=1;v<=n;v++){<br /> if(!a[v]&&cap[u][v]>flow[u][v]){<br /> p[v]=u; q.push(v);<br /> a[v]=a[u]<cap[u][v]-flow[u][v]?<br /> a[u]:cap[u][v]-flow[u][v];<br /> //regulator[v]-=a[v];<br /> }<br /> }<br /> }<br /> if(!a[t])<br /> break;<br /> //cout<<a[t]<<endl;<br /> for(u=t;u!=0;u=p[u]){<br /> flow[p[u]][u]+=a[t];//從匯點開始更新正向流<br /> flow[u][p[u]]-=a[t];//從匯點開始更新反向流<br /> //regulator[u]-=a[t];//從匯點開始更新regulator<br /> }<br /> f+=a[t];<br /> }<br /> return f;<br />}<br />int main()<br />{<br /> freopen("i.txt","r",stdin);<br /> int v1,v2,w;<br /> regulator[0]=INF;<br /> while(cin>>n){<br /> memset(cap,0,sizeof(cap));<br /> for(int i=1;i<=n;i++)<br /> cin>>regulator[i];<br /> cin>>m;<br /> for(int i=0;i<m;i++){<br /> cin>>v1>>v2>>w;<br /> cap[v1][v2]=smallest(w,regulator[v1],regulator[v2]);<br /> }<br /> cin>>startN>>sink;<br /> //cout<<startN<<" "<<sink<<endl;<br /> for(int i=0;i<startN;i++){<br /> cin>>v1;<br /> //cout<<v1<<endl;<br /> cap[0][v1]=regulator[v1];<br /> }</p><p> t=++n;<br /> regulator[t]=INF;<br /> for(int i=0;i<sink;i++){<br /> cin>>v1;<br /> cap[v1][t]=regulator[v1];<br /> }<br /> cout<<maxFlow()<<endl;<br /> }<br /> return 0;<br />}</p><p>
//最後才是對的做法,,就是拆點,,其實我第一個思路就是這個,只是當時覺得麻煩沒寫,其實一點都不麻煩
#include <iostream><br />#include <cstdio><br />#include <queue><br />#include <memory.h></p><p>using namespace std;<br />const int MAX=105*2,INF=1<<30;<br />int regulator[MAX],m,cap[MAX][MAX],flow[MAX][MAX],<br /> startN,sink,t,a[MAX],n,p[MAX],<br /> head[MAX],rear[MAX],dian;<br />queue<int> q;</p><p>int maxFlow(){<br /> memset(flow,0,sizeof(flow));<br /> int f=0,u;<br /> while(1){<br /> memset(a,0,sizeof(a));//a代表指向結點[v]的增廣路<br /> a[0]=INF;<br /> q.push(0);<br /> while(!q.empty()){<br /> u=q.front(); q.pop();<br /> for(int v=1;v<=n;v++){<br /> if(!a[v]&&cap[u][v]>flow[u][v]){<br /> p[v]=u; q.push(v);<br /> a[v]=a[u]<cap[u][v]-flow[u][v]?<br /> a[u]:cap[u][v]-flow[u][v];<br /> //regulator[v]-=a[v];<br /> }<br /> }<br /> }<br /> if(!a[t])<br /> break;<br /> //cout<<a[t]<<endl;<br /> for(u=t;u!=0;u=p[u]){<br /> flow[p[u]][u]+=a[t];//從匯點開始更新正向流<br /> flow[u][p[u]]-=a[t];//從匯點開始更新反向流<br /> //regulator[u]-=a[t];//從匯點開始更新regulator<br /> }<br /> f+=a[t];<br /> }<br /> return f;<br />}<br />int main()<br />{<br /> freopen("i.txt","r",stdin);<br /> int v1,v2,w;<br /> regulator[0]=INF;<br /> while(cin>>n){<br /> dian=1;<br /> memset(cap,0,sizeof(cap));<br /> for(int i=1;i<=n;i++){<br /> cin>>regulator[i];<br /> head[i]=dian; rear[i]=dian+1;<br /> cap[dian][dian+1]=regulator[i];<br /> dian+=2;<br /> }<br /> cin>>m;<br /> for(int i=0;i<m;i++){<br /> cin>>v1>>v2>>w;<br /> cap[rear[v1]][head[v2]]=w;<br /> }<br /> cin>>startN>>sink;<br /> //cout<<startN<<" "<<sink<<endl;<br /> for(int i=0;i<startN;i++){<br /> cin>>v1;<br /> //cap[0][v1]=regulator[v1];<br /> cap[0][head[v1]]=INF;<br /> }<br /> //t=++n;<br /> t=n=dian;<br /> //regulator[t]=INF;<br /> for(int i=0;i<sink;i++){<br /> cin>>v1;<br /> //cout<<v1<<endl;<br /> cap[rear[v1]][t]=INF;<br /> }<br /> /*for(int i=1;i<=n;i++){<br /> for(int j=1;j<=n;j++){<br /> cout<<cap[i][j]<<" ";<br /> }<br /> cout<<endl;<br /> }*/<br /> cout<<maxFlow()<<endl;<br /> }<br /> return 0;<br />}</p><p>
//為什麼我第2種方法是錯的,第3種是對的呢?,可以看一下資料
3<br />100 50 25<br />3<br />1 2 100<br />2 3 100<br />1 3 100<br />1 2<br />1 2 3<br />3<br />100 20 30<br />2<br />2 1 100<br />3 1 100<br />3 1<br />1 2 3 1</p><p>8<br />20 15 17 5 10 25 20 50<br />10<br />1 4 15<br />1 5 5<br />2 5 10<br />2 6 10<br />3 6 25<br />6 5 10<br />4 7 10<br />5 7 15<br />5 8 10<br />6 8 15<br />3 2<br />1 2 3 7 8<br />5<br />20 15 10 20 20<br />4<br />1 3 5<br />2 3 10<br />3 4 10<br />3 5 10<br />2 2<br />1 2 4 5</p><p>
//如果你仔細分析最後一個資料的結點5,你會發現第2種方法忽略了結點5的regulator是10的限制而讓5結點流出了 15的流量