Shoot the Bullet ZOJ - 3229有上下界网络流
Code:
#include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<iostream> #include<cstring> using namespace std; typedef long long ll; const int maxn=2005; const int maxd=1000000+233; const int INF=10000000; # define pb push_back int sss,ttt; int s,t; int E1,E2; int mapp[maxd],A[maxn],val[maxd]; struct Edge{ int from,to,cap; Edge(int u,int v,int c):from(u),to(v),cap(c) {} }; vector<Edge>edges; struct Dicnic{ vector<int>G[maxn]; int d[maxn],vis[maxn],cur[maxn]; queue<int>Q; void init(){ for(int i=0;i<maxn;++i)G[i].clear(); edges.clear(); } void addedge(int u,int v,int c,int cnt) { edges.pb(Edge(u,v,c)); edges.pb(Edge(v,u,0)); int m=edges.size(); G[u].pb(m-2); //正向弧 G[v].pb(m-1); //反向弧 E1=m-2,E2=m-1; if(cnt>0)mapp[cnt]=m-1; } int BFS() { memset(vis,0,sizeof(vis)); d[s]=0,vis[s]=1;Q.push(s); while(!Q.empty()) { int u=Q.front();Q.pop(); int sz=G[u].size(); for(int i=0;i<sz;++i){ Edge e=edges[G[u][i]]; if(!vis[e.to]&&e.cap>0&&e.to!=sss&&e.to!=ttt){ d[e.to]=d[u]+1,vis[e.to]=1; Q.push(e.to); } } } return vis[t]; } int dfs(int x,int a) { if(x==t)return a; int sz=G[x].size(); int f,flow=0; for(int i=cur[x];i<sz;++i) { Edge e=edges[G[x][i]]; cur[x]=i; if(d[e.to]==d[x]+1&&e.cap>0&&e.to!=sss&&e.to!=ttt) { f=dfs(e.to,min(a,e.cap)); if(f) { int u=G[x][i]; a-=f; edges[u].cap-=f; edges[u^1].cap+=f; flow+=f; if(a==0)break; } } } return flow; } int maxflow(){ int ans=0; while(BFS()){ memset(cur,0,sizeof(cur)); ans+=dfs(s,INF); } return ans; } }op; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { op.init(); memset(A,0,sizeof(A)); int sum=0,cnt=0,ss,tt; ss=0,tt=n+m+1; for(int i=0;i<m;++i){ int a;scanf("%d",&a); op.addedge(n+1+i,tt,INF-a,0); A[n+1+i]-=a,A[tt]+=a; } for(int i=1;i<=n;++i){ int c,d;scanf("%d%d",&c,&d); op.addedge(ss,i,d,0); for(int j=1;j<=c;++j) { int x,y,z; scanf("%d%d%d",&x,&y,&z); ++cnt; op.addedge(i,x+n+1,z-y,cnt); val[cnt]=y; A[i]-=y,A[x+n+1]+=y; } } s=1500,t=1501; for(int i=0;i<=n+m+1;++i) { if(A[i]>0){op.addedge(s,i,A[i],0);sum+=A[i];} if(A[i]<0)op.addedge(i,t,-A[i],0); } op.addedge(tt,ss,INF,0); sss=-1,ttt=-2; int ans1=op.maxflow(); sss=1500,ttt=1501; if(ans1!=sum){printf("-1\n");printf("\n");} else { ans1=edges[E2].cap; edges[E1].cap=edges[E2].cap=0; s=ss,t=tt; ans1+=op.maxflow(); printf("%d\n",ans1); for(int i=1;i<=cnt;++i) printf("%d\n",edges[mapp[i]].cap+val[i]); printf("\n"); } return 0; }