图论:无源汇有上下界可行流

一个网络,求出一个流,使得每条边的流量必须>=Li且<=Hi,每个点必须满足总流入量=总流出量(流量守恒)(这个流的特点是循环往复,无始无终).

如果有解的话输出每条边的流量

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 namespace DINIC
  5 {
  6     const int MAXN=500+10;
  7     const int MAXM=4e5+10;
  8     const int INF=0x3f3f3f3f;
  9     struct Edge
 10     {
 11         int u,v,cap,nxt;
 12         Edge(){}
 13         Edge(int _u,int _v,int _cap,int _nxt):u(_u),v(_v),cap(_cap),nxt(_nxt){}
 14     }E[MAXM];
 15     int head[MAXN],dis[MAXN],vis[MAXN];
 16     int tol;
 17     void init()
 18     {
 19         tol=0;
 20         memset(head,-1,sizeof(head));
 21     }
 22     void addedge(int u,int v,int cap)
 23     {
 24         E[tol]=Edge(u,v,cap,head[u]);//正向边
 25         head[u]=tol++;
 26         E[tol]=Edge(v,u,0,head[v]);//反向边容量为0
 27         head[v]=tol++;
 28     }
 29     bool BFS(int S,int T)
 30     {
 31         queue<int> q;
 32         q.push(S);
 33         memset(dis,0x3f,sizeof(dis));
 34         dis[S]=0;
 35         while(!q.empty())
 36         {
 37             int x=q.front();
 38             q.pop();
 39             for(int i=head[x];~i;i=E[i].nxt)
 40             {
 41                 if(E[i].cap>0&&dis[E[i].v]==INF)
 42                 {
 43                     dis[E[i].v]=dis[x]+1;
 44                     if(E[i].v==T)
 45                         return true;
 46                     q.push(E[i].v);
 47                 }
 48             }
 49         }
 50         return dis[T]<INF; //返回是否能够到达汇点
 51     }
 52     int dfs(int x,int maxflow,int T)
 53     {
 54         if(x==T||maxflow<=0)
 55             return maxflow;
 56         //i=vis[x]当前弧优化
 57         int ret=0;
 58         for(int &i=vis[x];~i;i=E[i].nxt)
 59         {
 60             if(dis[E[i].v]==dis[x]+1&&E[i].cap>0)
 61             {
 62                 int flow=dfs(E[i].v,min(maxflow,E[i].cap),T);
 63                 if(flow)
 64                 {
 65                     ret+=flow;
 66                     maxflow-=flow;
 67                     E[i].cap-=flow;//正向边流量降低
 68                     E[i^1].cap+=flow; //反向边流量增加
 69                 }
 70                 if(maxflow==0)
 71                     break;
 72             }
 73         }
 74         return ret;//找不到增广路退出
 75     }
 76     ll dinic(int S,int T,int N)
 77     {
 78         ll ans=0;
 79         while(BFS(S,T))//建立分层图
 80         {
 81             int flow;
 82             for(int i=0;i<=N;i++)//初始化vis
 83             {
 84                 vis[i]=head[i];
 85             }
 86             while(flow=dfs(S,INF,T))//一次BFS可以进行多次增广
 87                 ans+=(ll)flow;
 88         }
 89         return ans;
 90     }
 91 }
 92 using namespace DINIC;
 93 int a[MAXN],low[MAXM];
 94 int n,m;
 95 bool judge()
 96 {
 97     for(int i=head[0];~i;i=E[i].nxt)
 98     {
 99         if(E[i].cap!=0)
100             return false;
101     }
102     for(int i=head[n+1];~i;i=E[i].nxt)
103     {
104         if(E[i^1].cap!=0)
105             return false;
106     }
107     return true;
108 }
109 void solve()
110 {
111     int cnt;
112     memset(a,0,sizeof(a));
113     init();
114     for(int i=1;i<=m;i++)
115     {
116         int u,v,up;
117         scanf("%d%d%d%d",&u,&v,&low[i],&up);
118         a[v]+=low[i];a[u]-=low[i];
119         addedge(u,v,up-low[i]);
120     }
121     cnt=tol;
122     for(int i=1;i<=n;i++)
123     {
124         if(a[i]>0)
125             addedge(0,i,a[i]);
126         if(a[i]<0)
127             addedge(i,n+1,-a[i]);
128     }
129     dinic(0,n+1,n+2);
130     if(!judge())
131     {
132         puts("NO");
133         return ;
134     }
135     puts("YES");
136     for(int i=0;i<cnt;i+=2)
137     {
138         printf("%d\n",E[i^1].cap+low[i/2+1]);
139     }
140 }
141 int main()
142 {
143     //freopen("in.txt","r",stdin);
144     //freopen("out.txt","w",stdout);
145     while(~scanf("%d%d",&n,&m))
146     {
147         solve();
148     }
149     return 0;
150 }

 

posted @ 2018-09-10 22:57  静听风吟。  阅读(256)  评论(0编辑  收藏  举报