Cod sursa(job #578352)

Utilizator Alexa_ioana_14Antoche Ioana Alexandra Alexa_ioana_14 Data 11 aprilie 2011 11:15:01
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include<cstdio>
#include<algorithm>
#include<bitset>
#include<vector>
#include<queue>
#include<utility>
using namespace std;
#define pb push_back
#define mp make_pair
#define NM 605
#define II inline
#define fs first
#define sc second
#define sh short int
#define OO 1<<25
vector<pair<sh, int> >a[NM];
bitset<NM>viz;
sh N,M,x,y,t[NM],dest;
int z,s,flux,Q,c[NM][NM],m[NM][NM],dist[NM],f[NM][NM];
II void citire()
{
	freopen("cmcm.in","r",stdin);
	freopen("cmcm.out","w",stdout);
	scanf("%hd%hd%d",&N,&M,&Q);
	for (int i=1; i<=Q; ++i)
	{
		scanf("%hd%hd%d",&x,&y,&z);
		y+=N;
		a[x].pb(mp(y,z));
		a[y].pb(mp(x,-z));
		c[x][y]=1;
		m[x][y]=i;
	}
	for (int i=1; i<=N; ++i)
	{
		a[0].pb(mp(i,0));
		a[i].pb(mp(0,0));
		c[0][i]=1;
	}
	dest=N+1+M;
	for (int i=N+1; i<dest; ++i)
	{
		a[dest].pb(mp(i,0));
		a[i].pb(mp(dest,0));
		c[i][dest]=1;
	}
}
II int bf()
{
	queue<sh>q;
	for (int i=0; i<=dest; ++i)
	{
		dist[i]=OO;
		t[i]=-1;
		viz[i]=0;
	}
	q.push(0);
	viz[0]=1;
	dist[0]=0;
	int p=1;
	while (p)
	{
		x=q.front();
		q.pop();
		--p;
		viz[x]=0;
		int g=a[x].size();
		for (int i=0; i<g; ++i)
		{
			y=a[x][i].fs;
			if (c[x][y]>f[x][y] && dist[y]>dist[x]+a[x][i].sc)
			{
				t[y]=x;
				dist[y]=dist[x]+a[x][i].sc;
				if (viz[y])
					continue;
				viz[y]=1;
				q.push(y);
				++p;
			}
		}
	}
	if (dist[dest]==OO)
		return 0;
	int flux=OO;
	for (int i=dest; i; i=t[i])
		flux=(flux>c[t[i]][i]-f[t[i]][i])?(c[t[i]][i]-f[t[i]][i]):(flux);
	for (int i=dest; i; i=t[i])
	{
		f[t[i]][i]+=flux;
		f[i][t[i]]-=flux;
	}
	return flux*dist[dest];
}
II void cuplaj_maxim_de_cost_minim()
{
	int imp=1;
	while (imp)
	{
		imp=bf();
		s+=imp;
	}
}
II void afis()
{
	sh nr =0;
	for (int i=1; i<=N; ++i)
		for (int j=N+1; j<dest; ++j)
			if (c[i][j] && f[i][j])
			{
				++nr;
				break;
			}
	printf("%hd %d\n",nr,s);
	for (int i=1; i<=N; ++i)
		for (int j=N+1; j<dest; ++j)
			if (c[i][j] && f[i][j])
			{
				printf("%d ",m[i][j]);
				break;
			}
}
int main()
{
	citire();
	cuplaj_maxim_de_cost_minim();
	afis();
	return 0;
}