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 0x3f3f3f3f

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

 

posted @ 2014-08-14 00:56  chanme  阅读(140)  评论(0编辑  收藏  举报