sgu 176 Flow construction--有源汇 有上下界 最小流

来源:互联网 发布:天龙八部龙纹评分数据 编辑:程序博客网 时间:2024/05/22 04:26
/*SGU 176 Flow construction题意:有些节点(编号1~n,1为源,n为汇)和管道,用来运输某种物质(substance)某些管道必须满流,有些不必,找到一个最小流,满足要求输入:结束数目 管道数目管道{管道前节点,后节点,最大流量,是否需要满流(1需要0不需要)}就是求一个最小流http://blog.csdn.net/qq172108805/article/details/7802832有最小流做法*/#include<stdio.h>  #include<string.h>  #define inf 0x7fffffff  struct edge//边    {        int u,v,f,next,b,c;}e[15000];    int head[110],in[110],s,t,ss,tt,yong,sum,bian[11000];  int n,m; void ini()  {      memset(head,-1,sizeof(head));      yong=0;      memset(in,0,sizeof(in));      s=1,t=n,ss=0,tt=t+1;    sum=0;  memset(bian,0,sizeof(bian));} void adde(int from,int to,int xia,int shang)//加边    {   //加边        e[yong].u=from,e[yong].v=to,e[yong].f=shang-xia,e[yong].b=xia,e[yong].c=shang;        e[yong].next=head[from],head[from]=yong++;        //同时加它的退边        e[yong].u=to,e[yong].v=from,e[yong].f=0,e[yong].b=xia,e[yong].c=shang;        e[yong].next=head[to],head[to]=yong++;    } void build(){int i;        for(i=s;i<=t;++i)        {            if(in[i]>0)                adde(ss,i,0,in[i]);            else            {                adde(i,tt,0,-in[i]);                sum+=(-in[i]);            }        }   }int d[110],num[110];int min(int a,int b){return a<b?a:b;}    int sap_gap(int u,int f,int s,int t)//递归sap    {        if(u==t)            return f;        int i,v,mind=t,last=f,cost;        for(i=head[u];i!=-1;i=e[i].next)        {            v=e[i].v;            int flow=e[i].f;            if(flow>0)//参考模版写的时候把flow写成了f            {                if(d[u]==d[v]+1)                {                    cost=sap_gap(v,min(last,flow),s,t);                    e[i].f-=cost;                    e[i^1].f+=cost;                    last-=cost;                        if(d[s]>=t+1)                        return f-last;                        if(last==0)                        break;                }                if(d[v]<mind)                    mind=d[v];            }        }            if(last==f)        {            --num[d[u]];            if(num[d[u]]==0)                d[s]=t+1;            d[u]=mind+1;            ++num[d[u]];        }        return f-last;    }    int max_f(int s,int t)  {      int f=0;        memset(d,0,sizeof(d));        memset(num,0,sizeof(num));        for(num[s]=t+1;d[s]<t+1;)            f+=sap_gap(s,inf,s,t);        return f;   }int main(){int i,a,b,c,d,f1,f2,p;while(scanf("%d%d",&n,&m)!=EOF){ini();for(i=1;i<=m;i++){scanf("%d%d%d%d",&a,&b,&c,&d);if(d==0){bian[i]=yong;adde(a,b,0,c);}else{bian[i]=yong;adde(a,b,c,c);in[a]-=c;in[b]+=c;}}build();f1=max_f(ss,tt);      p=yong;  adde(t,s,0,inf);  f2=max_f(ss,tt); if(f1+f2!=sum) printf("Impossible\n");else{printf("%d\n",e[p^1].f);for(i=1;i<m;++i){printf("%d ",e[bian[i]].c-e[bian[i]].f);}printf("%d\n",e[bian[m]].c-e[bian[m]].f);}}return 0;}

原创粉丝点击