首页 > 代码库 > ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)

ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)

#pragma warning(disable:4996)#include <iostream>#include <cstring>#include <string>#include <vector>#include <cstdio>#include <algorithm>#include <cmath>#include <queue>#include <map>#include <stack>using namespace std;#define maxn 3000#define maxe 700000#define inf 0x3f3f3f3fstruct Edge{	int u, v, cap;	int nxt;}edge[maxe];int head[maxn];struct Dicnic{	int level[maxn];	int iter[maxn];	int add;	void init(){		add = 0; memset(head, -1, sizeof(head));		memset(iter, -1, sizeof(iter));	}	void insert(int u, int v, int c){		edge[add].u = u; edge[add].v = v; edge[add].cap = c;		edge[add].nxt = head[u]; head[u] = add++;		edge[add].u = v; edge[add].v = u; edge[add].cap = 0;		edge[add].nxt = head[v]; head[v] = add++;	}	void bfs(int s){		memset(level, -1, sizeof(level));		queue<int> que;		level[s] = 0;		que.push(s);		while (!que.empty()){			int v = que.front(); que.pop();			for (int i = head[v]; i != -1; i = edge[i].nxt){				Edge &e = edge[i];				if (e.cap > 0 && level[e.v] < 0){					level[e.v] = level[v] + 1;					que.push(e.v);				}			}		}	}	int dfs(int v, int t, int f){		if (v == t) return f;		for (int &i = iter[v]; i != -1; i = edge[i].nxt){			Edge &e = edge[i]; Edge &reve = edge[i ^ 1];			if (e.cap > 0 && level[v] < level[e.v]){				int d = dfs(e.v, t, min(f, e.cap));				if (d>0){					e.cap -= d; reve.cap += d;					return d;				}			}		}		return 0;	}	int max_flow(int s, int t){		int flow = 0;		for (;;){			bfs(s);			if (level[t] < 0) return flow;			memcpy(iter, head, sizeof(iter));			int f;			while ((f = dfs(s, t, inf))>0){				flow += f;			}		}	}}net;int n, m;int G[maxn];int mflow[400][1500];int main(){	while (~scanf("%d%d", &n, &m)){		int sum = 0;		net.init();		for (int i = 0; i < m; ++i) {			scanf("%d", G + i); sum += G[i];		}		int s = n + m + 1, t = s + 1;		int ss = t + 1, tt = ss + 1;		int C, D;		for (int i = 0; i < n; ++i){			scanf("%d%d", &C, &D);			net.insert(s, i, D);			int t, l, r;			for (int j = 0; j < C; ++j){				scanf("%d%d%d", &t, &l, &r);				mflow[i][t] = l;				sum += l;				net.insert(i, t + n, r - l);				net.insert(ss, t + n, l);				net.insert(i, tt, l);			}		}		for (int i = 0; i < m; ++i){			net.insert(i + n, t, inf);			net.insert(ss, t, G[i]);			net.insert(i + n, tt, G[i]);		}		net.insert(t, s, inf);		if (net.max_flow(ss, tt) != sum){			puts("-1\n"); continue;		}		net.insert(ss, s, inf);		net.insert(t, tt, inf);		int ans = net.max_flow(ss, tt);		printf("%d\n", ans);		stack<int> stk;		int from, to, cap;		for (int x = 0; x < n; ++x){			for (int k = head[x]; ~k; k = edge[k].nxt){				from = edge[k].u; to = edge[k].v; cap = edge[k ^ 1].cap;				if (to >= n&&to < n + m){					stk.push(cap + mflow[from][to - n]);					//printf("%d\n", cap + mflow[from][to - n]);				}			}			while (!stk.empty()){				printf("%d\n", stk.top());				stk.pop();			}		}		puts("");	}	return 0;}