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

猜你喜欢

转载自blog.csdn.net/liyong1009s/article/details/82779211