Cod sursa(job #796159)

Utilizator radustn92Radu Stancu radustn92 Data 10 octombrie 2012 19:26:56
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
#include <stdio.h>
#include <queue>
#include <vector>
#define NMAX 605
#define INF 1000000000
#define pb push_back
using namespace std;
int n,m,e,S,D,C[NMAX][NMAX],F[NMAX][NMAX],cost[NMAX][NMAX];
int best[NMAX],ant[NMAX],rez,cnt,edge[NMAX][NMAX];
bool find_way,in[NMAX];
vector <int> A[NMAX];
queue <int> Q;
void read()
{
	scanf("%d%d%d",&n,&m,&e);
	S=0; D=n+m+1;
	int i,x,y,z;
	for (i=1; i<=e; i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		edge[x][y+n]=i;
		cost[x][y+n]=z; cost[y+n][x]=-z; C[x][y+n]=1;
		A[x].pb(y+n); A[y+n].pb(x);
	}
	for (i=1; i<=n; i++)
	{
		A[S].pb(i); A[i].pb(S);
		C[S][i]=1;
	}
	for (i=1; i<=m; i++)
	{
		A[n+i].pb(D); A[D].pb(n+i);
		C[n+i][D]=1;
	}
}
void init()
{
	int i;
	for (i=S; i<=D; i++)
		best[i]=INF;
	best[S]=0;
	Q.push(S); in[S]=1;
}
inline int min(int x,int y)
{
	return x<y ? x : y;
}
int flow()
{
	init();
	int i,nod,vec;
	while (!Q.empty())
	{
		nod=Q.front();
		Q.pop(); in[nod]=0;
		for (i=0; i<A[nod].size(); i++)
		{
			vec=A[nod][i];
			if (C[nod][vec]-F[nod][vec]>0 && best[vec]>best[nod]+cost[nod][vec])
			{
				best[vec]=best[nod]+cost[nod][vec];
				ant[vec]=nod;
				if (!in[vec])
					Q.push(vec),in[vec]=1;
			}
		}
	}
	if (best[D]!=INF)
	{
		find_way=1;
		int fmin=INF;
		for (nod=D; nod!=S; nod=ant[nod])
			fmin=min(fmin,C[ant[nod]][nod]-F[ant[nod]][nod]);
		for (nod=D; nod!=S; nod=ant[nod])
		{
			F[ant[nod]][nod]+=fmin;
			F[nod][ant[nod]]-=fmin;
		}
		
		cnt+=fmin;
		return fmin*best[D];
	}
	return 0;
}
void solve()
{
	find_way=1;
	
	while (find_way)
	{
		find_way=0;
		rez+=flow();
	}
	
	printf("%d %d\n",cnt,rez);
	int i,j;
	for (i=1; i<=n; i++)
		for (j=1; j<=m; j++)
			if (F[i][j+n])
				printf("%d ",edge[i][j+n]);
	printf("\n");
}
int main()
{
	freopen("cmcm.in","r",stdin);
	freopen("cmcm.out","w",stdout);
	read();
	solve();
	return 0;
}