现在的位置: 首页 > 综合 > 正文

uva 10594 – Data Flow(费用流)

2014年10月02日 ⁄ 综合 ⁄ 共 1582字 ⁄ 字号 评论关闭

题目链接:uva 10594 - Data Flow

题目大意:给出一张图,然后给出K和D,D表示每条路的容量,然后由点1到点n运送数据,流量为K时的最小费用。


解题思路:和uva 10806 - Dijkstra, Dijkstra.做法一个样.....表示说不解释,就在起点0和1之间加条容量为K的路就好。



#include <stdio.h>
#include <string.h>
#include <queue>

#define ll long long
#define min(a,b) (a)<(b)?(a):(b)

using  namespace std;

const int MAXN = 50000;
ll INF = 1000000000000000;
const int N = 105;

struct edge {
	int next, im;
	int far, son;
	ll cap, flow;
	ll cost;
}s[MAXN];

int n, m, tmp, h[N];
ll K, D;

void add(int x, int y, ll c, ll cost, int im) {

	s[tmp].next = h[x];
	h[x] = tmp;

	s[tmp].im = tmp + im;
	s[tmp].far = x;
	s[tmp].son = y;
	s[tmp].cap = c;
	s[tmp].flow = 0;
	s[tmp].cost = cost;
	tmp++;
}

void init() {

	ll a[MAXN], b[MAXN], c[MAXN];

	tmp = 0;
	memset(h, -1, sizeof(h));

	for (int i = 0; i < m; i++)
		scanf("%lld%lld%lld", &a[i], &b[i], &c[i]);
	scanf("%lld%lld", &K, &D);

	add(0, 1, K, 0, 1);
	add(1, 0, 0, 0, -1);

	for (int i = 0; i < m; i++) {

		add(a[i], b[i], D, c[i], 1);
		add(b[i], a[i], 0, -c[i], -1);
		add(b[i], a[i], D, c[i], 1);
		add(a[i], b[i], 0, -c[i], -1);
	}
}

void solve() {
	queue<int> que;
	ll ans = 0, f = 0, d[N];
	int u, vis[N], path[MAXN];

	while (1) {

		for (int i = 0; i <= n + 1; i++) d[i] = (i == 0) ? 0 : INF;
		memset(path, -1, sizeof(path));
		memset(vis, 0, sizeof(vis));

		que.push(0);
		vis[0] = 1;

		while ( !que.empty() ) {
			u = que.front(), que.pop();
			vis[u] = 0;

			for (int i = h[u]; i != -1; i = s[i].next) {
				int v = s[i].son;
				if ( s[i].cap > s[i].flow && d[v] > d[u] + s[i].cost) {
					d[v] = d[u] + s[i].cost;
					path[v] = i;

					if (vis[v] == 0) {
						que.push(v);
						vis[v] = 1;
					}
				}
			}
		}

		if (d[n] == INF) break;
		ll a = INF;

		for (int i = n; i; i = s[path[i]].far)
			a = min(a, s[path[i]].cap - s[path[i]].flow);
		f += a;
		ans += a * d[n];

		for (int i = n; i; i = s[path[i]].far) {
			s[path[i]].flow += a;
			int im = s[path[i]].im;
			s[im].flow -= a;
		}
	}

	if (f < K)
		printf("Impossible.\n");
	else
		printf("%lld\n", ans);
}

int main () {

	while (scanf("%d%d", &n, &m) == 2) {
		init();
		solve();
	}
	return 0;
}


抱歉!评论已关闭.