ZOJ3229 Shoot the Bullet
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20756
思路:就讲一下有源汇上下界最大流的做法吧!对于所有的边,就按照无源汇的做法做,然后建一条(t->s,inf)的边,然后先算ss到tt的最大流,看是否满足下界,然后不管这个流的答案,清空cnt和dis,然后算出s->t的最大流,就是答案。
1 #include<cstdio> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #define inf 0x7fffffff 7 int dn[200005],id[200005]; 8 int tot,go[1000005],next[1000005],first[200005],flow[1000005]; 9 int n,m,du[200005],op[1000005],cnt[200005],dis[200005]; 10 int read(){ 11 int t=0,f=1;char ch=getchar(); 12 while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} 13 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 14 return t*f; 15 } 16 void insert(int x,int y,int z){ 17 tot++; 18 go[tot]=y; 19 next[tot]=first[x]; 20 first[x]=tot; 21 flow[tot]=z; 22 } 23 void add(int x,int y,int z){ 24 insert(x,y,z);op[tot]=tot+1; 25 insert(y,x,0);op[tot]=tot-1; 26 } 27 int dfs(int x,int f,int S,int T,int nodes){ 28 int mn=nodes,sum=0; 29 if (x==T) return f; 30 for (int i=first[x];i;i=next[i]){ 31 int pur=go[i]; 32 if (flow[i]&&dis[pur]+1==dis[x]){ 33 int F=std::min(flow[i],f-sum); 34 int save=dfs(pur,F,S,T,nodes); 35 sum+=save; 36 flow[i]-=save; 37 flow[op[i]]+=save; 38 if (sum==f||dis[S]>=nodes) return sum; 39 } 40 if (flow[i]) mn=std::min(mn,dis[pur]); 41 } 42 if (sum==0){ 43 cnt[dis[x]]--; 44 if (cnt[dis[x]]==0){ 45 dis[S]=nodes; 46 }else{ 47 dis[x]=mn+1; 48 cnt[dis[x]]++; 49 } 50 } 51 return sum; 52 } 53 int mxflow(int S,int T,int nodes){ 54 int res=0; 55 for (int i=0;i<=nodes;i++) cnt[i]=dis[i]=0; 56 while (dis[S]<nodes) 57 res+=dfs(S,inf,S,T,nodes); 58 return res; 59 } 60 int main(){ 61 freopen("tx.in","r",stdin); 62 int Nodes=0; 63 while (~scanf("%d%d",&n,&m)){ 64 for (int i=0;i<=Nodes;i++) first[i]=du[i]=0;tot=0; 65 int s=n+m+1,t=s+1; 66 int ss=t+1,tt=ss+1; 67 for (int i=1;i<=m;i++){ 68 int x=read(); 69 du[i]-=x; 70 du[t]+=x; 71 add(i,t,inf); 72 } 73 int Cnt=0; 74 for (int i=1;i<=n;i++){ 75 int c=read(),d=read(); 76 add(s,i+m,d); 77 while (c--){ 78 int x=read(),l=read(),r=read(); 79 du[i+m]-=l; 80 du[x+1]+=l; 81 dn[++Cnt]=l;id[Cnt]=tot+1; 82 add(i+m,x+1,r-l); 83 } 84 } 85 int sum=0; 86 for (int i=1;i<=t;i++) 87 if (du[i]>0) add(ss,i,du[i]),sum+=du[i]; 88 else add(i,tt,-du[i]); 89 add(t,s,inf); 90 if (sum!=mxflow(ss,tt,tt)) puts("-1"); 91 else{ 92 printf("%d\n",mxflow(s,t,tt)); 93 for (int i=1;i<=Cnt;i++) 94 printf("%d\n",dn[i]+flow[op[id[i]]]); 95 } 96 puts(""); 97 Nodes=tt; 98 } 99 }
**,没看到可能有多解,害我调了好久。。