#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100
#define INF 200000000
struct node{
int v,c,b;
node *next,*back;
}edge[MAXN*MAXN*2+1000],*adj[MAXN+10],*ecnt=&edge[0];
int n,m,du[MAXN+10],d[MAXN+10],vd[MAXN+10],e[MAXN*MAXN*2+1000],flow,tot,s,t,cnte;
void addedge(int u,int v,int c,int b)
{
// printf("***%d %d %d %d\n",u,v,c,b);
node *p=++ecnt; ++cnte;
p->v=v;
p->c=c,p->b=b;
p->next=adj[u],p->back=ecnt+1;
adj[u]=p;
p=++ecnt; ++cnte;
p->v=u;
p->c=0,p->b=b;
p->next=adj[v],p->back=ecnt-1;
adj[v]=p;
}
void limitflow(int x,int y,int c,int b)
{
addedge(x,y,c-b,b);
du[x]-=b,du[y]+=b;
}
void read()
{
int x,y,c,d;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&x,&y,&c,&d);
if(!d) limitflow(x,y,c,0);
else limitflow(x,y,c,c);
e[i]=cnte;
}
//limitflow(n,1,INF,0);
s=n+1,t=n+2;
for(int i=1;i<=n;i++){
if(du[i]>0) addedge(s,i,du[i],0),tot+=du[i];
if(du[i]<0) addedge(i,t,-du[i],0);
}
}
int aug(int u,int augc)
{
int augco=augc,mind=t,delta,v;
if(u==t)
return augc;
for(node *p=adj[u];p;p=p->next){
v=p->v;
if(p->c>0){
if(d[u]==d[v]+1){
delta=aug(v,min(augco,p->c));
p->c-=delta;
p->back->c+=delta;
augco-=delta;
if(d[s]>=t)
return augc-augco;
if(!augco)
break;
}
mind=min(mind,d[v]);
}
}
if(augco==augc){
vd[d[u]]--;
if(!vd[d[u]])
d[s]=t;
d[u]=mind+1;
vd[d[u]]++;
}
return augc-augco;
}
void Isap()
{
flow=0;
memset(d,0,sizeof d);
memset(vd,0,sizeof vd);
vd[0]=t;
while(d[s]<t)
flow+=aug(s,INF);
}
void workout()
{
printf("%d\n",flow);
for(int i=1;i<m;i++)
printf("%d ",edge[e[i]].c+edge[e[i]].b);
printf("%d\n",edge[e[m]].c+edge[e[m]].b);
}
bool Judge()
{
for(node *p=adj[s];p;p=p->next)
if(p->c)
return false;
return true;
}
int main()
{
read();
Isap(); //万一有环,应该充分利用环之后再建立edge(n,1,INF,0)
limitflow(n,1,INF,0);
Isap();
if(!Judge())
printf("Impossible\n");
else
workout();
}
SGU 176 Flow construction-上下界网络流
最新推荐文章于 2022-11-25 16:32:30 发布