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;

}

 

你可能感兴趣的:(最大流)