Cod sursa(job #428510)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 29 martie 2010 12:21:00
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.4 kb
#include<stdio.h>
#include<queue>
#include<vector>
#define Inf 1<<30
#define Nmax 700
#define Mmax 55000
#define Min(a,b) a<b ? a : b
using namespace std;

int Cmin[Nmax],H[Nmax],poz[Nmax],Cost[Nmax][Nmax],C[Nmax][Nmax],F[Nmax][Nmax],E[Nmax][Nmax],use[Mmax],T[Nmax];
int L,R,M,a,b,cst,i,Card,hL,D,S;
long long CostMinim,Sum;
bool in_queue[Nmax],drum=true;

vector<int> V[Nmax];
queue<int> Q;


void swap(int i, int j)
{
	poz[H[i]]=j;
	poz[H[j]]=i;
	int aux=H[i]; H[i]=H[j]; H[j]=aux;
}

int pozmin(int i)
{
	int k=i<<1;
	
	if(k+1<=hL)
		if(Cmin[H[k+1]]<Cmin[H[k]]) return k+1;
	return k;
}

void down(int i)
{
	int k;
	if(i<=(hL>>1))
	{
		k=pozmin(i);
		if(Cmin[H[k]]<Cmin[H[i]])
		{
			swap(i,k);
			down(k);
		}
	}
}

void up(int i)
{
	int k=i>>1;
	if(i>1)
	{
		if(Cmin[H[i]]<Cmin[H[k]])
		{
			swap(i,k);
			up(k);
		}
	}
}

void push(int x)
{
	H[++hL]=x;
	poz[x]=hL;
	up(hL);
}

void pop()
{
	swap(1,hL);
	poz[H[hL]]=0;
	H[hL--]=0;
	down(1);
}

void BellmanFord()
{
	int p,u,i,nod,fiu,cost,N;
	
	for(i=1;i<=D;i++)
		Cmin[i]=Inf;
	Cmin[S]=0;
	in_queue[S]=true;
	Q.push(S);
	
	for(p=u=1;p<=u;p++)
	{
		nod=Q.front();
		N=V[nod].size();
		in_queue[nod]=false;
		Q.pop();
		
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			cost=Cost[nod][fiu];
			
			if( C[nod][fiu] && Cmin[fiu] > Cmin[nod]+cost ) 
			{
				Cmin[fiu]=Cmin[nod]+cost;
				if(in_queue[fiu]==false)
				{
					in_queue[fiu]=true;
					Q.push(fiu);
					u++;
				}
			}
		}
	}
	Sum=Cmin[D];
}

int Dijkstra()
{
	int i,N,cost,nod,fiu,r;
	
	for(nod=1;nod<=D;nod++)
	{
		N=V[nod].size();
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			if(Cmin[nod]!=Inf && Cmin[fiu]!=Inf)
				Cost[nod][fiu]+=Cmin[nod]-Cmin[fiu];
		}
	}
	
	for(i=1;i<=D;i++)
	{
		T[i]=0;
		Cmin[i]=Inf;
	}
	
	Cmin[S]=0;
	H[1]=S; poz[S]=1; hL=1;
	
	while(hL)
	{
		nod=H[1];
		pop();
		
		N=V[nod].size();
		
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			cost=Cost[nod][fiu];
			
			if(Cmin[fiu] > Cmin[nod] + cost && C[nod][fiu]!=F[nod][fiu])
			{
				Cmin[fiu]=Cmin[nod]+cost;
				T[fiu]=nod;
				if(!poz[fiu]) push(fiu);
				else up(poz[fiu]);
				
			}
		}
	}
	
	if(Cmin[D]!=Inf)
	{
		drum=true;
		r=Inf;
		
		for(i=D;i!=S;i=T[i])
			r=Min(r,C[T[i]][i]-F[T[i]][i]);
		
		for(i=D;i!=S;i=T[i])
		{
			F[T[i]][i]+=r;
			F[i][T[i]]-=r;
		}
		
		Sum+=Cmin[D];
		return Sum*r;
	}
	return 0;
}

long long fmcm()
{
	long long flux=0;
	
	while(drum)
	{
		drum=false;
		flux+=Dijkstra();
	}
	return flux;
}

int main()
{
	freopen("cmcm.in","r",stdin);
	freopen("cmcm.out","w",stdout);
	
	scanf("%d %d %d",&L,&R,&M);
	
	S=1; D=L+R+2;
	
	for(i=1;i<=M;i++)
	{
		scanf("%d %d %d",&a,&b,&cst);
		
		a++; b+=L+1;
		
		V[a].push_back(b);
		V[b].push_back(a);
		
		C[a][b]=1;
		E[a][b]=i;
		
		Cost[a][b]=cst;
		Cost[b][a]=-cst;
	}
	
	for(i=2;i<=L+1;i++)
	{
		V[1].push_back(i);
		V[i].push_back(1);
		C[1][i]=1;
	}
	
	for(;i<D;i++)
	{
		V[i].push_back(D);
		V[D].push_back(i);
		C[i][D]=1;
	}
	
	BellmanFord();
	CostMinim=fmcm();
	int N,nod,fiu;
	
	for(nod=2;nod<=L+1;nod++)
	{
		N=V[nod].size();
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			if(C[nod][fiu] && C[nod][fiu]==F[nod][fiu]) 
				use[++Card]=E[nod][fiu];
		}
	}
	
	printf("%d %lld\n",Card,CostMinim);
	
	for(i=1;i<=Card;i++)
		printf("%d ",use[i]);
	
	return 0;
}