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


    一个网络,求出一个流,使得每条边的流量必须>=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
    ",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 }
  • 相关阅读:
    Java Calendar 类的时间操作
    Java获取当前时间的年月日方法
    CentOS7使用firewalld打开关闭防火墙与端口
    myEclipse开发内存溢出解决办法myEclipse调整jvm内存大小java.lang.OutOfMemoryError: PermGen space及其解决方法
    springMVC3学习--ModelAndView对象(转)
    form总结
    linux命令: chown命令
    fail2ban 保护
    centeros iptable模板文件
    Beetl2.2使用说明书20151201
  • 原文地址:https://www.cnblogs.com/aininot260/p/9623823.html
Copyright © 2020-2023  润新知