Cod sursa(job #2736243)

Utilizator Rares31100Popa Rares Rares31100 Data 3 aprilie 2021 11:58:30
Problema Cuplaj maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.67 kb
#include <bits/stdc++.h>
#define F first
#define S second

using namespace std;

ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
vector <int> gf[603], gft[603];
int cap[603][603], flux[603][603], cost[603][603];
int N, M, E;
int n, m, s, d, rezultat;

int dist[603];
void bellman_ford()
{
	for(int i = 1; i <= n; i++)
		if(i != s)
			dist[i] = 1 << 26;

	queue <int> q;
	bitset <603> inQ;
	q.push(s);
	inQ[s] = 1;

	while(!q.empty())
	{
		int nod = q.front();
		q.pop();
		inQ[nod] = 0;

		for(auto vec:gf[nod])
			if(dist[nod] + cost[nod][vec] < dist[vec])
			{
				dist[vec] = dist[nod] + cost[nod][vec];
				if(!inQ[vec])
				{
					q.push(vec);
					inQ[vec] = 1;
				}
			}
	}
}
int positiveDist[603], tata[603], tabelTata[603], newDist[603];
bool djikstra()
{
	for(int i = 1; i <= n; i++)
		if(i != s)
			positiveDist[i] = 1 << 26;

	priority_queue <pair<int, int>> pq;
	bitset <603> viz;
	pq.push({0, s});

	while(!pq.empty())
	{
		int nod = pq.top().second;
		pq.pop();

		if(viz[nod] == 1)
			continue;
		viz[nod] = 1;

		for(auto vec:gf[nod])
		{
			int positiveArc = cost[nod][vec] + dist[nod] - dist[vec];
			if(cap[nod][vec] && positiveDist[nod] + positiveArc < positiveDist[vec])
			{
				positiveDist[vec] = positiveDist[nod] + positiveArc;
				pq.push({-positiveDist[vec], vec});
				newDist[vec] = newDist[nod] + cost[nod][vec];

				tata[vec] = nod;
				tabelTata[vec] = 1;
			}
		}

		for(auto vec:gft[nod])
		{
			int positiveArc = -cost[vec][nod] + dist[nod] - dist[vec];
			if(flux[nod][vec] && positiveDist[nod] + positiveArc < positiveDist[vec])
			{
				positiveDist[vec] = positiveDist[nod] + positiveArc;
				pq.push({-positiveDist[vec], vec});
				newDist[vec] = newDist[nod] - cost[vec][nod];

				tata[vec] = nod;
				tabelTata[vec] = 2;
			}
		}
	}

	for(int i = 1; i <= n; i++)
		dist[i] = newDist[i];

	if(positiveDist[d] != (1 << 26))
		return true;
	return false;
}
pair <int, int> muchie[603];
int tabel[603];
void drum(int lung)
{
	int minim = 1 << 26, suma = 0;

	for(int i = 1; i <= lung; i++)
		if(tabel[i] == 1)
			minim = min(minim, cap[ muchie[i].F ][ muchie[i].S ]);
		else
			minim = min(minim, flux[ muchie[i].F ][ muchie[i].S ]);

	for(int i = 1; i <= lung; i++)
		if(tabel[i] == 1)
		{
			suma += cost[ muchie[i].F ][ muchie[i].S ] * minim;
			cap[ muchie[i].F ][ muchie[i].S ] -= minim;
			flux[ muchie[i].S ][ muchie[i].F ] += minim;
		}
		else
		{
			suma += -cost[ muchie[i].S ][ muchie[i].F ] * minim;
			flux[ muchie[i].F ][ muchie[i].S ] -= minim;
			cap[ muchie[i].S ][ muchie[i].F ] += minim;
		}

	rezultat += suma;
}

pair <int, int> muchii[601];
int nrUsed;

int main()
{
	fin >> N >> M >> E;
	n = N + M + 2;
	m = E;
	s = 1;
	d = N + M + 2;

	for(int k = 1, i, j, Cost; k <= m; k++)
	{
		fin >> i >> j >> Cost;
		i += 1;
		j += N + 1;

		muchii[k] = {i, j};
		gf[i].push_back(j);
		gft[j].push_back(i);
		cap[i][j] = 1;
		cost[i][j] = Cost;
	}

	for(int i = 2; i <= N + 1; i++)
	{
		gf[s].push_back(i);
		gft[i].push_back(s);
		cap[s][i] = 1;
	}

	for(int i = N + 2; i <= N + M + 1; i++)
	{
		gf[i].push_back(d);
		gft[d].push_back(i);
		cap[i][d] = 1;
	}

	bellman_ford();

	while(djikstra())
	{
		int nod = d, vf = 0;
		while(nod != s)
		{
			muchie[++vf] = {tata[nod], nod};
			tabel[vf] = tabelTata[nod];
			nod = tata[nod];
		}
		
		drum(vf);
	}

	for(int i = 1; i <= m; i++)
		if(!cap[ muchii[i].first ][ muchii[i].second ])
			nrUsed++;

	fout << nrUsed << ' ' << rezultat << '\n';

	for(int i = 1; i <= m; i++)
		if(!cap[ muchii[i].first ][ muchii[i].second ])
			fout << i << ' ';

	return 0;
}