(一道模板題) 無源匯有上下界可行流
阿新 • • 發佈:2018-01-27
edi block html else printf ack 分類 tex long long
題目描述
這是一道模板題。
n 個點,m 條邊,每條邊 e 有一個流量下界 lower(e) 和流量上界 upper(e),求一種可行方案使得在所有點滿足流量平衡條件的前提下,所有邊滿足流量限制。
輸入格式
第一行兩個正整數 n 、m 。
之後的 m 行,每行四個整數 s 、t 、lower 、upper。
輸出格式
如果無解,輸出一行 NO
。
否則第一行輸出 YES
,之後 m 行每行一個整數,表示每條邊的流量。
樣例
樣例輸入 1
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
樣例輸出 1
NO
樣例輸入 2
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
樣例輸出 2
YES
1
2
3
2
1
1
數據範圍與提示
N<=200,M<=10200
分類標簽
模板 上下界網絡流 網絡流 碼了一天了懶得再打一下上下界網絡流原理來,,,就是一個流量平衡。#include<bits/stdc++.h> #define ll long long #define maxn 1005 #define pb push_back using namespace std;const int inf=1<<29; vector<int> g[maxn]; struct lines{ int to,flow,cap; }l[maxn*maxn]; int t=-1,S,T,n,m; int d[maxn],cur[maxn]; bool v[maxn]; inline void add(int xx,int yy,int zz){ l[++t]=(lines){yy,0,zz},g[xx].pb(t); l[++t]=(lines){xx,0,0},g[yy].pb(t); } inline bool bfs(){ queue<int> q; memset(v,0,sizeof(v)); d[S]=0,v[S]=1,q.push(S); int x; lines e; while(!q.empty()){ x=q.front(),q.pop(); for(int i=g[x].size()-1;i>=0;i--){ e=l[g[x][i]]; if(!v[e.to]&&e.flow<e.cap){ d[e.to]=d[x]+1; v[e.to]=1; q.push(e.to); } } } return v[T]; } int dfs(int x,int a){ if(x==T||!a) return a; int flow=0,f,sz=g[x].size(); for(int &i=cur[x];i<sz;i++){ lines &e=l[g[x][i]]; if(d[x]==d[e.to]-1&&(f=dfs(e.to,min(a,e.cap-e.flow)))){ flow+=f,a-=f; e.flow+=f,l[g[x][i]^1].flow-=f; if(!a) break; } } return flow; } inline int max_flow(){ int an=0; while(bfs()){ memset(cur,0,sizeof(cur)); an+=dfs(S,inf); } return an; } int low[maxn*50],inflow[maxn],tot=0; int main(){ int uu,vv,r; scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ scanf("%d%d%d%d",&uu,&vv,low+i,&r); add(uu,vv,r-low[i]); inflow[vv]+=low[i]; inflow[uu]-=low[i]; } S=0,T=n+1; for(int i=1;i<=n;i++){ if(inflow[i]>0){ add(S,i,inflow[i]); tot+=inflow[i]; } else if(inflow[i]) add(i,T,-inflow[i]); } if(tot!=max_flow()) puts("NO"); else{ puts("YES"); for(int i=0;i<m;i++) printf("%d\n",low[i]+l[i<<1].flow); } return 0; }
(一道模板題) 無源匯有上下界可行流