Cod sursa(job #481713)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 1 septembrie 2010 14:05:39
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <fstream>
#include <queue>
using namespace std;

const int NMAX=303;
const int MMAX=303;
const int Inf=0x3f3f3f3f;

int N,M,E,cost[NMAX][MMAX],idx[NMAX][MMAX],dr[NMAX],st[MMAX];
int d[NMAX+MMAX],from[NMAX+MMAX];
bool inQ[NMAX+MMAX];

int main()
{
	int i,j;
	ifstream fin("cmcm.in");
	fin>>N>>M>>E;

	for (i=1;i<=N;++i)
		for (j=1;j<=M;++j)
			cost[i][j]=Inf;

	for (i=1;i<=E;++i)
	{
		int x,y,z;
		fin>>x>>y>>z;
		if (cost[x][y] > z)
		{
			cost[x][y]=z;
			idx[x][y]=i;
		}
	}

	int cost_min=0;
	int cup_max=0;

	bool ok=true;
	while (ok)
	{
		queue<int> Q;
		ok=false;
		for (i=1;i<=N+M;++i) d[i]=Inf,inQ[i]=false;

		for (i=1;i<=N;++i)
			if (!dr[i]) d[i]=0,Q.push(i),inQ[i]=true,from[i]=0;

		for (;!Q.empty();Q.pop())
		{
			int x=Q.front();
			if (x<=N)
			{
				for (j=1;j<=M;++j)
					if (cost[x][j] < Inf && st[j]!=x)
					  if (d[j+N] > d[x] + cost[x][j])
					  {
						  d[j+N]=d[x]+cost[x][j];
						  from[j+N]=x;
						  if (!inQ[j+N]) Q.push(j+N),inQ[j+N]=true;
					  }
			}
			else
				if (st[x-N] && d[st[x-N]] > d[x] - cost[st[x-N]][x-N])
					{
						d[st[x-N]]=d[x]-cost[st[x-N]][x-N];
						from[st[x-N]]=x;
						if (!inQ[st[x-N]]) Q.push(st[x-N]),inQ[st[x-N]]=true;
					}
			
			inQ[x]=false;
		}

		int dmin=Inf,ret=0;
		for (i=1;i<=M;++i)
			if (!st[i] && dmin > d[i+N])
				dmin=d[i+N],ret=i;

		if (dmin < Inf)
		{
			ok=true;
			cost_min+=dmin;
			++cup_max;

			for (i=ret+N;i;i=from[i])
				if (i>N)
				{
					st[i-N]=from[i];
					dr[from[i]]=i-N;
				}
		}
	}

	ofstream fout("cmcm.out");
	fout<<cup_max<<" "<<cost_min<<"\n";
	for (i=1;i<=N;++i)
		if (dr[i])
			fout<<idx[i][dr[i]]<<" ";

	return 0;
}