Pagini recente » Cod sursa (job #2095310) | Monitorul de evaluare | Sedinta 2008-10-21 | Lambru Andrei Cristian | Cod sursa (job #2390909)
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <climits>
#include <algorithm>
#define MAXN (605)
using pii = std::pair<int, int>;
std::vector<pii> listN[MAXN];
int cap[MAXN][MAXN];
int flow[MAXN][MAXN];
int edgeIndex[MAXN][MAXN];
bool bellmanFord(int N, int src, int dst)
{
std::vector<int> que[2] = {std::vector<int>(N+1), std::vector<int>(N+1)};
std::vector<int> d(N, INT_MAX/2);
std::vector<int> parent(N, -1);
std::vector<int> isInQue(N);
int fst = 0, lst = 1;
que[fst][0] = 1;
que[fst][1] = src;
d[src] = 0;
for (int step = 1; step <= N+1; ++ step, fst ^= 1, lst ^= 1) {
que[lst][0] = 0;
for (int k = 1; k <= que[fst][0]; ++ k) {
int curNode = que[fst][k];
for (auto nb : listN[curNode]) {
if (cap[curNode][nb.first] - flow[curNode][nb.first] > 0 && d[nb.first] > d[curNode] + nb.second) {
d[nb.first] = d[curNode] + nb.second;
parent[nb.first] = curNode;
if (isInQue[nb.first] != step) {
isInQue[nb.first] = step;
que[lst][++que[lst][0]] = nb.first;
}
}
}
}
}
if (d[dst] < (INT_MAX/2)) {
int minFlow = INT_MAX/2;
for (int pathN = dst; pathN != 0; pathN = parent[pathN]) {
minFlow = std::min(minFlow, cap[parent[pathN]][pathN]-flow[parent[pathN]][pathN]);
}
for (int pathN = dst; pathN != 0; pathN = parent[pathN]) {
flow[parent[pathN]][pathN] += minFlow;
flow[pathN][parent[pathN]] -= minFlow;
}
return 1;
}
return 0;
}
int main ()
{
/* code */
std::ifstream in("cmcm.in");
int N, M, E;
in >> N >> M >> E;
int src = 0, dst = N+M+1;
for (int i = 0; i < E; ++ i) {
int x, y, c;
in >> x >> y >> c;
listN[x].push_back({y + N, c});
listN[y + N].push_back({x, -c});
cap[x][y + N] = 1;
edgeIndex[x][y + N] = i+1;
}
in.close();
for (int i = 1; i <= N; ++ i) {
listN[0].push_back({i, 0});
cap[0][i] = 1;
}
for (int i = 1; i <= M; ++ i) {
listN[N + i].push_back({dst, 0});
cap[N + i][dst] = 1;
}
while (bellmanFord(N + M + 2, src, dst));
int cost = 0;
std::vector<int> edges;
for (int i = 1; i <= N; ++ i) {
for (auto n : listN[i]) {
int node = n.first;
if (cap[i][node] == flow[i][node]) {
cost += n.second * flow[i][node];
edges.push_back(edgeIndex[i][node]);
}
}
}
std::ofstream out("cmcm.out");
out << edges.size() << " " << cost << "\n";
for(auto e : edges) {
out << e << " ";
}
out << "\n";
out.close();
return 0;
}