這是一道模板題n 個點,m 條邊,每條邊 e 有一個流量下界 lower(e)(和流量上界 upper(e) ,求一種可行方案使得在全部點知足流量平衡條件的前提下,全部邊知足流量限制。html
第一行兩個正整數 n 、m 。node
以後的 m行,每行四個整數 s 、t 、lower 、upper 。c++
若是無解,輸出一行 NO
。ui
不然第一行輸出 YES
,以後 m 行每行一個整數,表示每條邊的流量。spa
4 6 1 2 1 2 2 3 1 2 3 4 1 2 4 1 1 2 1 3 1 2 4 2 1 2
NO
4 6 1 2 1 3 2 3 1 3 3 4 1 3 4 1 1 3 1 3 1 3 4 2 1 3
YES 1 2 3 2 1 1
1≤n≤200,1≤m≤10200 code
模板題;其實能夠就是經過某種建圖,而後取跑最大流,但是否滿流。htm
具體建圖方式: 創建源點S 匯點T, 每條邊創建 x ->y,flow=(最大流)-(最小流),同時創建每一個點流入流出狀況d[i],即d[x]-=流出,d[y]+=流入,輸出是最小流+跑完最大流後每條邊上的流量。blog
#include <bits/stdc++.h> using namespace std; const int MAXN=10200+10; const int MAXM=10200+10; const int INF=0x3f3f3f3f; int ss,tt; struct node{ int v,next,flow; }edge[MAXN*10]; int head[MAXN],cnt=0,cur[MAXN]; int d[MAXN],st[MAXM]; void ADD(int x,int y,int flow) { edge[cnt].v=y; edge[cnt].flow=flow; edge[cnt].next=head[x]; head[x]=cnt++; edge[cnt].v=x; edge[cnt].flow=0; edge[cnt].next=head[y]; head[y]=cnt++; } int dis[MAXN]; bool bfs() { memset(dis,-1, sizeof(dis)); queue<int >qu; while(!qu.empty()) qu.pop(); qu.push(ss); dis[ss]=0; int u,v; while (!qu.empty()) { u=qu.front(); qu.pop(); for (int i = head[u]; i !=-1 ; i=edge[i].next) { v=edge[i].v; if(dis[v]==-1&&edge[i].flow>0) { dis[v]=dis[u]+1; qu.push(v); if(v==tt) break; } } } return dis[tt]!=-1; } int dfs(int u,int cap) { if(u==tt||cap==0) return cap; int res=0,v,f; for (int &i = cur[u]; i !=-1; i=edge[i].next) { v=edge[i].v; if(dis[v]==dis[u]+1&&(f=dfs(v,min(cap-res,edge[i].flow)))>0) { edge[i].flow-=f; edge[i^1].flow+=f; res+=f; if(res==cap) return cap; } } if(!res) dis[u]=-1; return res; } int dinic() { int ans=0; while(bfs()) { for (int i = 0; i <=tt ; ++i) { cur[i]=head[i]; } ans+=dfs(ss,INF); } return ans; } int main() { int n,m; memset(head,-1, sizeof(head)); memset(d,0, sizeof(d)); memset(st,0, sizeof(st)); scanf("%d%d",&n,&m); ss=0;tt=n+1; int x,y,low,up; for (int i = 0; i <m ; ++i) { scanf("%d%d%d%d",&x,&y,&low,&up); ADD(x,y,up-low); d[x]-=low; d[y]+=low; st[i]=low; } int sum=0; for (int i = 1; i <=n ; ++i) { if(d[i]>0) sum+=d[i]; ADD(ss,i,d[i]); if(d[i]<0) ADD(i,tt,-d[i]); } if(dinic()!=sum) { printf("NO\n"); return 0; } else { printf("YES\n"); for (int i = 0; i <m ; ++i) { printf("%d\n",edge[i*2|1].flow+st[i]); } } return 0; } //loj115