無匯源有上下界網路流zoj 2314
阿新 • • 發佈:2018-12-09
設超級源點st,匯點ed;
對於一個點i;
設low[i]為其上界w為其下界,有flow=w-low[i];
if(flow>0)add(st,i,flow)
if(flow<0)add(i,ed,-flow)
求st->ed最大流,看是不是滿流(st鄰邊都滿流)。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <iostream> using namespace std; #define INF 0x3f3f3f3f struct node { int u,v,val,next; }e[1111111]; int st,ed,n,m; int head[1111111],cur[1111111],top; int dis[1111111]; int low[111111]; int in[111111]; void add1(int u,int v,int val) { e[top].u=u; e[top].v=v; e[top].val=val; e[top].next=head[u]; head[u]=top++; } void add(int u,int v,int val) { add1(u,v,val); add1(v,u,0); } int bfs() { memset(dis,0,sizeof dis); dis[st]=1; queue<int>q; q.push(st); while(!q.empty()) { int f=q.front(); q.pop(); if(f==ed)return 1; for(int i=head[f];i!=-1;i=e[i].next) { int v=e[i].v; if(!dis[v]&&e[i].val) { dis[v]=dis[f]+1; q.push(v); } } } return 0; } int dfs(int u,int maxf,int t) { if(u==t)return maxf; int res=0; for(int &i=cur[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].val&&dis[v]==dis[u]+1) { int f=dfs(v,min(maxf-res,e[i].val),t); e[i].val-=f;e[i^1].val+=f; res+=f; if(res==maxf)return res; } } return res; } int dinic() { int ans=0; while(bfs()) { memcpy(cur,head,sizeof head); ans+=dfs(st,INF,ed); } return ans; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); st=0,ed=n+1; memset(head,-1,sizeof head); memset(in,0,sizeof in); top=0; for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d",&u,&v); scanf("%d%d",&low[i],&w); in[u]-=low[i];in[v]+=low[i]; add(u,v,w-low[i]); } for(int i=1;i<=n;i++) { if(in[i]>0)add(st,i,in[i]); else add(i,ed,-in[i]); } dinic(); int ans=0; int flag=0; for(int i=head[st];i!=-1;i=e[i].next) if(e[i].val){flag=1;break;}; if(flag) { printf("NO\n"); } else { printf("YES\n"); for(int i=0;i<m;i++) printf("%d\n",e[(i<<1)^1].val+low[i]); } } }