Cod sursa(job #470683)

Utilizator ooctavTuchila Octavian ooctav Data 15 iulie 2010 11:34:31
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int NMAX = 305;
const int MMAX = 305;
const int T_NOD = NMAX + MMAX + 2;
const int INF = 1<<30;

int N, M, E;
vector<int> G[T_NOD];
int cost[T_NOD][T_NOD];
int C[T_NOD][T_NOD];
int F[T_NOD][T_NOD];
int ord[T_NOD][T_NOD];
int S, D;
int tata[T_NOD];
int dist[T_NOD];
int REZ = 0;
int mch[T_NOD];

void citi()
{
	cin >> N >> M >> E;
	S = 0;
	D = N + M + 1;
	int x, y, c;
	for(int i = 1 ; i <= E ; i++)
	{
		cin >> x >> y >> c;
		y += N;
		G[x].push_back(y);
		G[y].push_back(x);
		cost[x][y] = c;
		cost[y][x] = -c;
		C[x][y] = 1;
		ord[x][y] = i;
	}
	for(int i = 1 ; i <= N ; i++)
	{
		G[S].push_back(i);
		G[i].push_back(S);
		C[S][i] = 1;
	}
	for(int i = N + 1 ; i <= N + M ; i++)
	{
		G[i].push_back(D);
		G[D].push_back(i);
		C[i][D] = 1;
	}
}

bool BF()
{
	queue<int> Q;
	bool in_coada[T_NOD] = {0};
	fill(dist + 1, dist + N + M + 2, INF);
	Q.push(S);
	in_coada[S] = 1;
	
	while(!Q.empty())
	{
		int nod = Q.front();
		Q.pop();
		in_coada[nod] = 0;
		for(vector<int> :: iterator it = G[nod].begin() ; it != G[nod].end() ; it++)
			if(dist[nod] + cost[nod][*it] < dist[*it] && F[nod][*it] < C[nod][*it])
			{
				dist[*it] = dist[nod] + cost[nod][*it];
				tata[*it] = nod;
				if(!in_coada[*it])
				{
					Q.push(*it);
					in_coada[*it] = 1;
				}
			}
	}
	
	return dist[D] != INF;
}

void flux()
{
	int FLUX;
	while(BF())
	{
		FLUX = INF;
		for(int nod = D ; nod != S ; nod = tata[nod])
			FLUX = min(FLUX, C[tata[nod]][nod] - F[tata[nod]][nod]);
		for(int nod = D ; nod != S ; nod = tata[nod])
		{
			F[tata[nod]][nod] += FLUX;
			F[nod][tata[nod]] -= FLUX;
		}
		REZ += FLUX * dist[D];
	}
}

void cauta_muchii()
{
	for(int i1 = 1 ; i1 <= N ; i1++)
		for(int i2 = N + 1 ; i2 <= N + M ; i2++)
			if(F[i1][i2] > 0 && F[i1][i2] == C[i1][i2])
				mch[++mch[0]] = ord[i1][i2];
}

void scrie()
{
	printf("%d ",mch[0]);
	printf("%d\n", REZ);
	for(int i = 1 ; i <= mch[0] ; i++)
		printf("%d ", mch[i]);
}

int main()
{
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out", "w", stdout);
	citi();
	flux();
	cauta_muchii();
	scrie();
	return 0;
}