Cod sursa(job #2586927)

Utilizator CyborgSquirrelJardan Andrei CyborgSquirrel Data 21 martie 2020 19:09:49
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("cmcm.in");
ofstream fout("cmcm.out");

const int NM = 410*2;
const int INF = 0x3f3f3f3f;

int n, m, e;
vector<int> gra[NM];
int cap[NM][NM], flo[NM][NM];
int dst[NM][NM], ind[NM][NM];

void read(){
	fin >> n >> m >> e;
	for(int i = 1; i <= e; ++i){
		int a, b;
		fin >> a >> b;
		b += n;
		
		fin >> dst[a][b];
		dst[b][a] = -dst[a][b];
		
		cap[a][b] = 1;
		gra[a].push_back(b);
		gra[b].push_back(a);
		
		ind[a][b] = ind[b][a] = i;
	}
}

int s, d;
void setup(){
	s = 0;
	d = n+m+1;
	for(int i = 1; i <= n; ++i){
		cap[s][i] = 1;
		gra[s].push_back(i);
	}
	for(int i = 1; i <= m; ++i){
		cap[i+n][d] = 1;
		gra[i+n].push_back(d);
	}
}

queue<int> qu;
bool inqu[NM];
int tdst[NM], dad[NM];
void nuke(){
	for(int i = 0; i <= n+m+1; i++){
		tdst[i] = INF;
	}
}

bool bellman(){
	nuke();
	qu.push(s);
	tdst[s] = 0;
	while(!qu.empty()){
		int a = qu.front();
		qu.pop();
		inqu[a] = false;
		for(auto b : gra[a]){
			int v = tdst[a]+dst[a][b];
			if(v < tdst[b] && flo[a][b] < cap[a][b]){
				tdst[b] = v;
				dad[b] = a;
				if(!inqu[b]){
					qu.push(b);
					inqu[b] = true;
				}
			}
		}
	}
	return tdst[d]!=INF;
}

void flowit(){
	int fmin = INF;
	for(int x = d; x != s; x = dad[x]){
		fmin = min(fmin, cap[dad[x]][x] - flo[dad[x]][x]);
	}
	for(int x = d; x != s; x = dad[x]){
		flo[dad[x]][x] += fmin;
		flo[x][dad[x]] -= fmin;
	}
}

int edges = 0, cost = 0;

void solve(){
	setup();
	while(bellman()){
		flowit();
		edges++;
		cost += tdst[d];
	}
}

void write(){
	fout << edges << " " << cost << "\n";
	for(int a = 1; a <= n; ++a){
		for(int b = 1; b <= m; ++b){
			if(flo[a][b+n] == 1){
				fout << ind[a][b+n] << " ";
			}
		}
	}
}

int main(){
	// ios_base::sync_with_stdio(false);
	read();
	solve();
	write();
	return 0;
}