Cod sursa(job #1133803)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 5 martie 2014 17:23:47
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <fstream>
#include <vector>
//#include <list>
#include <queue>
#include <limits>

const int INF=std::numeric_limits<int>::max() / 2;


int main(){
	std::ifstream fin("cmcm.in");
	std::ofstream fout("cmcm.out");

	unsigned n,m,e; fin>>n>>m>>e;

	std::vector< std::vector<unsigned> > edgenr(n+m+2,std::vector<unsigned>(n+m+2,0));
	std::vector< std::vector<unsigned> > F(n+m+2,std::vector<unsigned>(n+m+2,0));
	std::vector< std::vector<int> > cost(n+m+2,std::vector<int>(n+m+2,INF));
	std::vector< std::vector<unsigned> > Adj(n+m+2);

	//citire muchii
	for(unsigned i=1;i<=e;++i){
		unsigned x,y; int c;
		fin>>x>>y>>c; y+=n;
		F[x][y]=1;
		cost[x][y]=c;
		cost[y][x]=-c;
		edgenr[x][y]=i;
		Adj[x].push_back(y);
		Adj[y].push_back(x);
	}

	//noduri si muchii speciale
	for(unsigned i=1;i<=n;++i){
		F[0][i]=1; cost[0][i]=0;
		Adj[0].push_back(i); Adj[i].push_back(0);
	}
	for(unsigned i=n+1;i<=n+m;++i){
		F[i][n+m+1]=1; cost[i][n+m+1]=0;
		Adj[i].push_back(n+m+1); Adj[n+m+1].push_back(i);
	}


	int cost_total=0;

	//fmcm cu Belman-Ford
	bool cont=true;
	while(cont){
		std::vector<int> dist(n+m+2,INF);
		std::vector<unsigned> tati(n+m+2);

		std::queue<unsigned> q;
		q.push(0); dist[0]=0;

		while(!q.empty()){
            unsigned t=q.front(); q.pop();

            for(auto it=Adj[t].begin();it!=Adj[t].end();++it)
				if(F[t][*it] && dist[*it]>dist[t]+cost[t][*it]){
					dist[*it]=dist[t]+cost[t][*it];
					q.push(*it);
					tati[*it]=t;
				}

		}

		if(dist[n+m+1]!=INF){
			for(unsigned i=n+m+1;i!=0;i=tati[i]){
				F[tati[i]][i]-=1;
				F[i][tati[i]]+=1;
			}

			cost_total+=dist[n+m+1];
		}
		else cont=false;
	}

	unsigned nr=0;
	for(unsigned i=1;i<=n;++i)
		for(unsigned j=n+1;j<=n+m;++j)
			if(F[j][i]){ ++nr; break; }

	fout<<nr<<' '<<cost_total<<'\n';

	for(unsigned i=1;i<=n;++i)
		for(unsigned j=n+1;j<=n+m;++j)
			if(F[j][i]){ fout<<edgenr[i][j]<<' '; break; }

	fout<<'\n';
}