/* 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; }