Cod sursa(job #2632629)

Utilizator Leonard123Mirt Leonard Leonard123 Data 4 iulie 2020 10:58:53
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
	
#include <stdio.h>
#include <string.h>
#include <algorithm>
 
using namespace std;
 
#define MAX_N 710
#define inf 2000000000
#define pb push_back
 
int n, m, e, k, dest, sol, nr, improve;
int tata[MAX_N], dist[MAX_N];
int C[MAX_N][MAX_N], F[MAX_N][MAX_N], edge[MAX_N][MAX_N];
 
struct muchie {
	int a, b, c;
} v[120010];
 
void cit() {
	scanf("%d %d %d", &n, &m, &e);
	for (int i = 1; i <= e; i++) {
		k++;
    	scanf("%d %d %d", &v[k].a, &v[k].b, &v[k].c);
		v[k].a++; v[k].b += n + 1;
		edge[v[k].a][v[k].b] = i;
		C[v[k].a][v[k].b] = 1;
 
		k++;
		v[k] = v[k - 1]; 
		swap(v[k].a, v[k].b);
		v[k].c *= (-1);
	}
}
 
void build_graph() {
	//sursa este nodul 1, destinatia n + m + 2
	dest = n + m + 2;
	for (int i = 2; i <= n + 1; i++) {
		v[++k].a = 1; v[k].b = i;
		v[++k].a = i; v[k].b = 1;
 
		C[1][i] = 1;
	}
	for (int i = n + 2; i <= n + m + 1; i++) {
		v[++k].a = i; v[k].b = dest;
		v[++k].a = dest; v[k].b = i;	
	
		C[i][dest] = 1;
	}
}
 
void relax(int u, int v, int val) {
	if (dist[u] != inf && C[u][v] > F[u][v] && dist[v] > dist[u] + val) {
    	dist[v] = dist[u] + val;
		tata[v] = u;
	}
}
 
int bellman_ford() {
	for (int i = 1; i <= dest; i++) {
    	dist[i] = inf;
		tata[i] = -1;
	}
	dist[1] = 0;
 
	for (int i = 0; i <= n; i++)
		for (int j = 1; j <= k; j++)
			relax(v[j].a, v[j].b, v[j].c);
 
    if (dist[dest] < inf) {
		int flux = inf;
		for (int i = dest; i != 1; i = tata[i])
			flux = min(flux, C[tata[i]][i] - F[tata[i]][i]);
 
		for (int i = dest; i != 1; i = tata[i]) {
			F[tata[i]][i] += flux;
			F[i][tata[i]] -= flux;
		}
 
		return flux * dist[dest];	 
	}
	return 0;
}
 
void solve() {
	//construiesc graful de flux
	build_graph();
 
	improve = 1;
	while (improve) {
    	improve = bellman_ford();
		sol += improve;
    }  
}
 
void write() {
	for (int i = 2; i <= n + 1; i++)
		for (int j = n + 2; j < dest; j++)
			if (C[i][j] && F[i][j]) {
				nr++;
				break;
			}
 
	printf("%d %d\n", nr, sol);
    for (int i = 2; i <= n + 1; i++)
        for (int j = n + 2; j < dest; j++)
            if (C[i][j] && F[i][j]) {
				printf("%d ", edge[i][j]);
                break;
            }
	printf("\n"); 
}
 
int main() {
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out", "w", stdout);
 
	cit();
	solve();
	write();
 
	return 0;
}