【题意】
给出一些边流量的上界和下界,问能否循环流通。
【思路】
黄学长讲得很清楚,直接贴过来:
上界用ci表示,下界用bi表示。
下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– bi。
主要思想:每一个点流进来的流=流出去的流
对于每一个点i,令
Mi= sum(i点所有流进来的下界流)– sum(i点所有流出去的下界流)
*PO主注:下界流指的就是输入的下界
如果Mi大于0,代表此点必须还要流出去Mi的自由流,那么我们从源点连一条Mi的边到该点。
如果Mi小于0,代表此点必须还要流进来Mi的自由流,那么我们从该点连一条Mi的边到汇点。
如果求S->T的最大流,看是否满流(S的相邻边都流满)。
满流则有解,否则无解。
【错误点】
忘记清空vector和in数组了orz
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #define target n+1 8 using namespace std; 9 const int MAXM=100000+5; 10 const int MAXN=200+5; 11 const int INF=0x7fffffff; 12 struct node 13 { 14 int to,pos,cap; 15 }; 16 vector<node> E[MAXM]; 17 int n,m,sum=0; 18 int in[MAXN]; 19 int dist[MAXN]; 20 int low[MAXM];//记录下每条边的下界 21 int edge[MAXM][2]; 22 23 void addedge(int u,int v,int c) 24 { 25 E[u].push_back((node){v,E[v].size(),c}); 26 E[v].push_back((node){u,E[u].size()-1,0}); 27 } 28 29 void init() 30 { 31 memset(in,0,sizeof(in));//不要忘记了要清空in 32 for (int i=0;i<target;i++) E[i].clear();//不要忘记了要清空vector 33 int u,v,c; 34 for (int i=0;i<m;i++) 35 { 36 scanf("%d%d%d%d",&u,&v,&low[i],&c); 37 in[u]-=low[i]; 38 in[v]+=low[i]; 39 addedge(u,v,c-low[i]); 40 edge[i][0]=v; 41 edge[i][1]=E[v].size()-1; 42 } 43 sum=0; 44 for (int i=1;i<=n;i++) 45 { 46 if (in[i]>0) 47 { 48 addedge(0,i,in[i]); 49 sum+=in[i]; 50 } 51 else if (in[i]<0) addedge(i,target,-in[i]); 52 } 53 } 54 55 int bfs() 56 { 57 memset(dist,-1,sizeof(dist)); 58 queue<int> que; 59 while (!que.empty()) que.pop(); 60 que.push(0); 61 dist[0]=0; 62 63 while (!que.empty()) 64 { 65 int head=que.front(); 66 que.pop(); 67 for (int i=0; i<E[head].size(); i++) 68 { 69 node &tmp=E[head][i]; 70 if (dist[tmp.to]==-1 && tmp.cap>0) 71 { 72 dist[tmp.to]=dist[head]+1; 73 que.push(tmp.to); 74 if (tmp.to==target) return 1; 75 } 76 } 77 } 78 return 0; 79 } 80 81 int dfs(int s,int e,int maxflow) 82 { 83 int ret=0; 84 if (s==e || maxflow==0) return maxflow; 85 for (int i=0;i<E[s].size();i++) 86 { 87 node &tmp=E[s][i]; 88 if (dist[tmp.to]==dist[s]+1 && tmp.cap>0) 89 { 90 int delta=dfs(tmp.to,e,min(maxflow,tmp.cap)); 91 if (delta>0) 92 { 93 ret+=delta; 94 tmp.cap-=delta; 95 E[tmp.to][tmp.pos].cap+=delta; 96 maxflow-=delta; 97 } 98 } 99 } 100 return ret; 101 } 102 103 void dinic() 104 { 105 int flow=0; 106 while (bfs()) 107 { 108 int f=dfs(0,target,INF); 109 if (f>0) 110 flow+=f; 111 else break; 112 } 113 if (flow!=sum) cout<<"NO"<<endl; 114 else 115 { 116 cout<<"YES"<<endl; 117 for (int i=0;i<m;i++) cout<<low[i]+E[edge[i][0]][edge[i][1]].cap<<endl; 118 } 119 } 120 121 int main() 122 { 123 while (~(scanf("%d%d",&n,&m))) 124 { 125 init(); 126 dinic(); 127 } 128 return 0; 129 }