http://acm.sgu.ru/problem.php?contest=0&problem=194
题意:m条有向边,有上下界,求最大流。
思路:原图中有u-v low[i],high[i] 建图就是u->v,high[i]-low[i],同时du[u]-=low[i],du[v]+=low[i],然后对于每个点i,如果du[i]>0,那就S->i,du[i],若是du[i]<0那就i->T ,-du[i],然后判断S出去的流是不是满流,不是就无解,否则每条边流量就是基础流量再加上附加流。
啊♂,一开始脑抽了,反向边流量忘记变成0了。。
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #define inf 0x7fffffff 7 int S,T,nodes; 8 int id[200005]; 9 int tot,go[200005],next[200005],dn[200005],first[200005],flow[200005]; 10 int dis[200005],cnt[200005],op[200005],ans[200005],du[200005],n,m; 11 int read(){ 12 char ch=getchar();int t=0,f=1; 13 while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} 14 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 15 return t*f; 16 } 17 void insert(int x,int y,int z,int Id){ 18 tot++; 19 go[tot]=y; 20 next[tot]=first[x]; 21 first[x]=tot; 22 flow[tot]=z; 23 id[tot]=Id; 24 } 25 void add(int x,int y,int z,int Id){ 26 insert(x,y,z,Id);op[tot]=tot+1; 27 insert(y,x,0,0);op[tot]=tot-1; 28 } 29 int dfs(int x,int f){ 30 if (x==T) return f; 31 int mn=nodes,sum=0; 32 for (int i=first[x];i;i=next[i]){ 33 int pur=go[i]; 34 if (flow[i]&&dis[pur]+1==dis[x]){ 35 int save=dfs(pur,std::min(f-sum,flow[i])); 36 sum+=save; 37 flow[i]-=save; 38 flow[op[i]]+=save; 39 if (dis[S]>=nodes||f==sum) return sum; 40 } 41 if (flow[i]) mn=std::min(mn,dis[pur]); 42 } 43 if (sum==0){ 44 cnt[dis[x]]--; 45 if (cnt[dis[x]]==0) 46 dis[S]=nodes; 47 else 48 dis[x]=mn+1,cnt[dis[x]]++; 49 } 50 return sum; 51 } 52 int main(){ 53 while (~scanf("%d%d",&n,&m)){ 54 for (int i=0;i<=n+2;i++) dis[i]=cnt[i]=first[i]=du[i]=0; 55 tot=0;S=0;T=n+1;nodes=T+1; 56 for (int i=1;i<=m;i++){ 57 int u=read(),v=read(),lf=read(),hf=read(); 58 add(u,v,hf-lf,i); 59 du[u]-=lf; 60 du[v]+=lf; 61 dn[i]=lf; 62 } 63 for (int i=1;i<=n;i++){ 64 if (du[i]>0) add(S,i,du[i],0); 65 if (du[i]<0) add(i,T,-du[i],0); 66 } 67 int Ans; 68 while (dis[S]<nodes) Ans+=dfs(S,inf); 69 bool flag=true; 70 for (int i=first[S];i;i=next[i]) 71 if (flow[i]!=0){ 72 flag=false; 73 break; 74 } 75 if (!flag) { 76 puts("NO"); 77 continue; 78 }else{ 79 puts("YES"); 80 for (int i=1;i<=tot;i++) ans[id[i]]=flow[op[i]]; 81 for (int i=1;i<=m;i++) printf("%d ",dn[i]+ans[i]); 82 } 83 } 84 }