Cod sursa(job #1398923)

Utilizator vladrochianVlad Rochian vladrochian Data 24 martie 2015 14:18:29
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_set>
#include <cstring>
using namespace std;

const int kMaxN = 605;
const int kInf = 0x3f3f3f3f;

int N, M, E, dest;
vector<pair<int, int>> G[kMaxN];
int indx[kMaxN][kMaxN];
bool cap[kMaxN][kMaxN];
unordered_set<int> used_edges;
int cost;

int dist[kMaxN], padre[kMaxN];
struct HeapNode {
	int node, cost;
	HeapNode(int n, int c) : node(n), cost(c) {}
	bool operator<(const HeapNode &other) const {
		return cost > other.cost;
	}
};
priority_queue<HeapNode> q;

void BuildGraph() {
	ifstream fin("cmcm.in");
	fin >> N >> M >> E;
	dest = N + M + 2;
	for (int i = 1; i <= E; ++i) {
		int x, y, c;
		fin >> x >> y >> c;
		++x;
		y += N + 1;
		G[x].emplace_back(y, c);
		G[y].emplace_back(x, -c);
		indx[x][y] = i;
		indx[y][x] = -i;
		cap[x][y] = true;
	}
	for (int i = 2; i <= N + 1; ++i) {
		G[1].emplace_back(i, 0);
		G[i].emplace_back(1, 0);
		cap[1][i] = true;
	}
	for (int i = N + 2; i < dest; ++i) {
		G[i].emplace_back(dest, 0);
		G[dest].emplace_back(i, 0);
		cap[i][dest] = true;
	}
}

bool Dijkstra() {
	memset(dist, kInf, sizeof dist);
	dist[1] = 0;
	q.emplace(1, 0);
	while (!q.empty()) {
		int node = q.top().node;
		int cost = q.top().cost;
		q.pop();
		if (cost != dist[node])
			continue;
		for (auto it : G[node])
			if (cap[node][it.first] && dist[node] + it.second < dist[it.first]) {
				dist[it.first] = dist[node] + it.second;
				padre[it.first] = node;
				q.emplace(it.first, dist[it.first]);
			}
	}
	return dist[dest] < kInf;
}

void Solve() {
	while (Dijkstra()) {
		for (int i = dest; i != 1; i = padre[i]) {
			cap[padre[i]][i] = false;
			cap[i][padre[i]] = true;
			int edge = indx[padre[i]][i];
			if (edge > 0)
				used_edges.insert(edge);
			else
				used_edges.erase(-edge);
		}
		cost += dist[dest];
	}
}

void Print() {
	ofstream fout("cmcm.out");
	fout << used_edges.size() << " " << cost << "\n";
	for (int i : used_edges)
		fout << i << " ";
	fout << "\n";
}

int main() {
	BuildGraph();
	Solve();
	Print();
	return 0;
}