zoj2314

题解:

有上限的网络流

基本模板

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int ne[N],num,n,m,d[N],S,T,a,b,c,low[N],fi[N],zz[N],sl[N],dis[N],q[N];
void jb(int x,int y,int z)
{
    ne[num]=fi[x];
    fi[x]=num;
    zz[num]=y;
    sl[num++]=z;
    swap(x,y);
    z=0;
    ne[num]=fi[x];
    fi[x]=num;
    zz[num]=y;
    sl[num++]=z;    
}
int bfs()
{
    memset(dis,0xff,sizeof dis);
    dis[1]=0;
    int l=0,r=1;
    q[1]=1;
    while (l<r)
     {
         int j=q[++l];
         for (int i=fi[j];i!=-1;i=ne[i])
          if (dis[zz[i]]<0&&sl[i]>0)
           {
               dis[zz[i]]=dis[j]+1;
               q[++r]=zz[i];
           }
     }
    if (dis[n]>0)return 1;
    return 0; 
}
int find(int x,int low)
{
    int b=0;
    if (x==n)return low;
    for (int i=fi[x];i!=-1;i=ne[i])
     if (sl[i]>0&&dis[zz[i]]==dis[x]+1&&(b=find(zz[i],min(low,sl[i]))))
      {
          sl[i]-=b;
          sl[i^1]+=b;
          return b;
      }
    return 0;  
}
int main()
{
    scanf("%d",&T);
    while (T--)
     {
         memset(fi,-1,sizeof fi);
         num=0;
         memset(d,0,sizeof d);
         scanf("%d%d",&n,&m);
         for (int i=0;i<m;i++)
          {
              scanf("%d%d%d%d",&a,&b,&low[i],&c);
              jb(a+1,b+1,c-low[i]);
              d[a]+=low[i];d[b]-=low[i]; 
          }
         int tot=0;
        for (int i=1;i<=n;i++)
         {
             if (d[i]<0)jb(1,i+1,-d[i]);
             else jb(i+1,n+2,d[i]),tot+=d[i];
         } 
        n+=2; 
        int t,ans=0; 
        while (bfs()) 
         while (t=find(1,1e9))ans+=t;
        if (tot!=ans)puts("NO");
        else 
         {
             puts("YES");
             for (int i=0;i<m;i++)
              printf("%d
",sl[(i<<1)^1]+low[i]);
         } 
        puts(""); 
     }
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8406986.html