Pagini recente » Cod sursa (job #156807) | Cod sursa (job #2930920) | Cod sursa (job #2984347) | Cod sursa (job #2131598) | Cod sursa (job #371538)
Cod sursa(job #371538)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const char iname[] = "cmcm.in";
const char oname[] = "cmcm.out";
#define MAXN 605
vector < pair < pair <int, int>, pair <int, int> > > edges;
int capacity[MAXN][MAXN], flow_cost;
int getAugmentation(int n, int src, int dst) {
const int inf = 0x3f3f3f3f;
vector < pair < pair <int, int>, pair <int, int> > >::iterator it;
vector <int> d(n + 1, inf), p(n + 1, -1);
d[src] = 0;
for (int i = 1; i < n; ++ i) {
for (it = edges.begin(); it != edges.end(); ++ it) {
int x = it->first.first;
int y = it->first.second;
int cost = it->second.first;
if (capacity[x][y] > 0) if (d[x] < inf) if (d[y] > d[x] + cost)
d[y] = d[x] + cost,
p[y] = x;
}
}
if (p[dst] != -1) {
flow_cost += d[dst];
for (int i = dst; i != src; i = p[i])
capacity[p[i]][i] ^= 1, capacity[i][p[i]] ^= 1;
return 1;
}
return 0;
}
int main(void) {
ifstream in(iname);
int cardL, cardR, cardEdges;
assert(in >> cardL >> cardR >> cardEdges);
assert(1 <= cardL && cardL <= 300);
assert(1 <= cardR && cardR <= 300);
assert(1 <= cardEdges && cardEdges <= 50000);
int source = 0;
int sink = cardL + cardR + 1;
for (int i = 0; i < cardEdges; ++ i) {
int x, y, cost;
in >> x >> y >> cost;
edges.push_back(make_pair(make_pair(x, y + cardL), make_pair(cost, i)));
capacity[x][y + cardL] = 1;
edges.push_back(make_pair(make_pair(y + cardL, x), make_pair(-cost, i)));
}
for (int i = 1; i <= cardL; ++ i)
edges.push_back(make_pair(make_pair(source, i), make_pair(0, -1))),
capacity[source][i] = 1;
for (int j = 1; j <= cardR; ++ j)
edges.push_back(make_pair(make_pair(j + cardL, sink), make_pair(0, -1))),
capacity[j + cardL][sink] = 1;
while (getAugmentation(cardL + cardR + 2, source, sink)) ;
vector < pair < pair <int, int>, pair <int, int> > >::iterator it;
vector <int> r_edges;
int r_flow_cost = 0;
for (it = edges.begin(); it != edges.end(); ++ it) {
int x = it->first.first;
int y = it->first.second;
if (1 <= x && x <= cardL) if (1 <= y - cardL && y - cardL <= cardR)
if (capacity[x][y] == 0)
r_edges.push_back(it->second.second),
r_flow_cost += it->second.first;
}
assert(flow_cost == r_flow_cost);
ofstream out(oname);
out << r_edges.size() << " " << r_flow_cost << "\n";
for (int i = 0; i < r_edges.size(); ++ i)
out << r_edges[i] + 1 << " ";
in.close();
return 0;
}