Cod sursa(job #1966431)

Utilizator lflorin29Florin Laiu lflorin29 Data 15 aprilie 2017 11:37:19
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.98 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_EDGES = 2 * 70003 + 9, MAX_N = 502 * 2 + 5, INF = 1e9 + 2;

int src, dest, n, m, e, tata[MAX_N], vis[MAX_N], dp[MAX_N];
int x[MAX_EDGES], y[MAX_EDGES], cost[MAX_EDGES], cap[MAX_EDGES], f[MAX_EDGES];
vector<int>g[MAX_N];

int flow, costflow;

void Add (int a, int b, int c, int capnow, int i)
{
	x[2 * i] = a, y[2 * i] = b, cost[2 * i] = c, cap[2 * i] = capnow;
	x[2 * i + 1] = b, y[2 * i + 1] = a, cost[2 * i + 1] = -c, cap[2 * i + 1] = 0;
	g[a].push_back(2 * i);
	g[b].push_back(2 * i + 1);
}

bool Bellman()
{
	queue<int>q;
	memset(tata, 0, sizeof tata), memset(vis, 0, sizeof vis);

	for (int i = 1; i <= n + m + 2; ++i)
		dp[i] = INF + 3;

	dp[src] = 0;
	q.push(src);

	while (!q.empty())
	{
		int nod = q.front();
		q.pop();
		vis[nod] = 0;

		for (auto i : g[nod])
		{
			if (dp[nod] < dp[y[i]] - cost[i] && cap[i] - f[i] > 0)
			{
				tata[y[i]] = i;
				dp[y[i]] = dp[nod] + cost[i];

				if (!vis[y[i]])
				{
					vis[y[i]] = 1;
					q.push(y[i]);
				}
			}

		}
	}

	return dp[dest] < INF;
}

void Increase()
{
	int mn = INF;

	for (int i = dest; i != src; i = x[tata[i]])
		mn = min(mn, cap[tata[i]] - f[tata[i]]);

	costflow += mn * dp[dest];
	flow += mn;

	for (int i = dest; i != src; i = x[tata[i]])
	{
		f[tata[i]] += mn, f[tata[i] ^ 1] -= mn;
	}
}

int main()
{
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out", "w", stdout);

	scanf("%d%d%d", &n, &m, &e);
	src = 0;
	dest = n + m + 1;

	for (int i = 1; i <= e; ++i)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		b += n;
		Add(a, b, c, 1, i);
	}

	for (int i = 1; i <= n; ++i)
	{
		Add(src, i, 0, 1, ++e);
	}

	for (int i = n + 1; i <= m + n; ++i)
	{
		Add(i, dest, 0, 1, ++e);
	}

	while (Bellman ())
	{
		Increase ();
	}

	printf("%d %d\n", flow, costflow);

	for (int i = 1; i <= n; ++i)
	{
		for (auto j : g[i])
		{
			if(f[j] > 0)
			printf("%d ", j / 2);
		}
	}
}