Pagini recente » Cod sursa (job #1433183) | Cod sursa (job #804726) | Cod sursa (job #1581170) | Cod sursa (job #1328580) | Cod sursa (job #2020162)
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
using namespace std;
ifstream in("cmcm.in");
ofstream out("cmcm.out");
const int nmax = 300;
const int inf = 1000000000;
int n;
int cost[1 + nmax][1 + nmax];
int index[1 + nmax][1 + nmax];
int etu[1 + nmax], etv[1 + nmax];
int visu[1 + nmax], visv[1 + nmax];
int cuplaj[1 + nmax];
int dfs(int u1) {
visu[u1] = 1;
for(int v1 = 1; v1 <= n; v1++) {
int exces = etu[u1] + etv[v1] - cost[u1][v1];
if(visv[v1] == 0 && exces == 0) {
visv[v1] = 1;
if(cuplaj[v1] == 0 || dfs(cuplaj[v1]) == 1) {
cuplaj[v1] = u1;
return 1;
}
}
}
return 0;
}
void hungarian() {
for(int i = 1; i <= n; i++) {
etu[i] = -inf;
for(int j = 1; j <= n; j++) {
etu[i] = max(etu[i], cost[i][j]);
}
etv[i] = 0;
}
for(int i=1; i<=n; i++) { //iteratii
while(dfs(i) == 0) {
// cout<<":";
//atata timp cat nu am gasit drum de augmentare, relaxez vis-urile <=> updatez etichetele
int epsilon = inf;
for(int j = 1; j <= n; j++)
if(visv[j] == 0) {
for(int k = 1; k <= n; k++) {
if(visu[k] == 1) {
epsilon = min(epsilon, etu[k] + etv[j] - cost[k][j]);
}
}
}
//cout<<epsilon<<endl;
for(int j = 1; j <= n; j++) {
if(visu[j] == 1) {
etu[j] -= epsilon;
visu[j] = 0;
}
if(visv[j] == 1) {
etv[j] += epsilon;
visv[j] = 0;
}
}
}
}
}
int main() {
int nedge, m;
in >> n >> m >> nedge;
//rezolvam problema determinarii costului maxim
n = max(n, m);
for(int i = 1; i <= n; i++) {
fill(cost[i] + 1, cost[i] + n + 1, -inf);
}
for(int i = 1; i <= nedge; i++) {
int from, to, c;
in >> from >> to >> c;
cost[from][to] = -c;
index[from][to] = i;
}
/*
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cout << cost[i][j] << ' ';
}
cout << '\n';
}
*/
hungarian();
int sum = 0;
vector<int> edges;
for(int i = 1; i <= n; i++) {
if(cuplaj[i] != 0 && index[cuplaj[i]][i] != 0) {
edges.push_back(index[cuplaj[i]][i]);
sum += cost[cuplaj[i]][i];
}
}
out << edges.size() << ' ' << -sum << '\n';
for(int i = 0; i < edges.size(); i++)
out << edges[i] << ' ';
in.close();
out.close();
return 0;
}