Pagini recente » Cod sursa (job #36010) | Cod sursa (job #87469) | Cod sursa (job #894734) | Cod sursa (job #3256769) | Cod sursa (job #2764087)
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
int n, m, E;
vector<pair<int, int>> a[705];
int C[705][705], F[705][705], edge[705][705];
int sol;
int t[705];
const int Inf = 1e9;
void read() {
int i, x, y, cost;
ifstream f("cmcm.in");
f >> n >> m >> E;
for (i = 1; i <= E; i++) {
f >> x >> y >> cost; x++, y += 1 + n;
a[x].emplace_back(y, cost);
a[y].emplace_back(x, -cost);
C[x][y] = 1;
edge[x][y] = i;
}
f.close();
}
void buildGraph() {
int sink = n + m + 2, i;
for (i = 2; i <= n + 1; i++) {
a[1].emplace_back(i, 0);
a[i].emplace_back(1, 0);
C[1][i] = 1;
}
for (i = n + 2; i <= n + m + 1; i++) {
a[i].emplace_back(sink, 0);
a[sink].emplace_back(i, 0);
C[i][sink] = 1;
}
}
queue<int> Q;
bool viz[705];
int d[705];
int bellmanford() {
int i, x;
for (i = 1; i <= n + m + 2; i++) {
d[i] = Inf;
viz[i] = 0;
t[i] = -1;
}
viz[1] = 1;
d[1] = 0;
Q.push(1);
while (!Q.empty()) {
x = Q.front();
Q.pop();
viz[x] = 0;
for (i = 0; i < a[x].size(); i++)
if (F[x][a[x][i].first] != C[x][a[x][i].first] && d[x] + a[x][i].second < d[a[x][i].first]) {
d[a[x][i].first] = d[x] + a[x][i].second;
t[a[x][i].first] = x;
if (!viz[a[x][i].first]) {
viz[a[x][i].first] = 1;
Q.push(a[x][i].first);
}
}
}
// ford-fulkerson
if (d[n + m + 2] < Inf) {
int flux = Inf;
int nod = n + m + 2;
while (nod != 1) {
flux = min(flux, C[t[nod]][nod] - F[t[nod]][nod]);
nod = t[nod];
}
nod = n + m + 2;
while (nod != 1) {
F[t[nod]][nod] += flux;
F[nod][t[nod]] -= flux;
nod = t[nod];
}
return flux * d[n + m + 2];
}
return 0;
}
void solve() {
int i, improve;
buildGraph();
improve = 1;
while (improve) {
improve = bellmanford();
sol += improve;
}
}
void output() {
ofstream g("cmcm.out");
int i, j, nr = 0;
for (i = 2; i <= n + 1; i++)
for (j = n + 2; j <= n + m + 1; j++)
if (C[i][j] && F[i][j])
nr++;
g << nr << ' ' << sol << '\n';
for (i = 2; i <= n + 1; i++)
for (j = n + 2; j <= n + m + 1; j++)
if (C[i][j] && F[i][j])
g << edge[i][j] << ' ';
g.close();
}
int main() {
read();
solve();
output();
return 0;
}