Pagini recente » Cod sursa (job #885610) | Borderou de evaluare (job #133080) | Cod sursa (job #2378553) | Cod sursa (job #2257496) | Cod sursa (job #1688873)
#include <fstream>
#include <vector>
using namespace std;
ifstream in("cmcm.in");
ofstream out("cmcm.out");
int n,m;
const int MAXN = 710;
const int INF = 1 << 30;
vector<int> vecini[MAXN], cost[MAXN];
int idmuchie[MAXN][MAXN];//idmuchie[i][j] - indicele muchiei intre i si j
int capacitate[MAXN][MAXN];//Atentie! Trebuie cu matrice de adiacenta deoarece avem nevoie de capacitatea intre doua noduri in O(1)
int flux[MAXN][MAXN];//Atentie! Trebuie cu matrice de adiacenta deoarece avem nevoie de fluxul intre doua noduri in O(1)
int sursa,destinatie;
void citire()
{
int e;
in >> n >> m >> e;
for (int i = 1;i <= e;++i)
{
int x,y,c;
in >> x >> y >> c;
++x;// muchiile x si y
y += n + 1;//sunt iduri din doua multimi, deci le concatenam
vecini[x].push_back(y);
cost[x].push_back(c);
//construim graful rezidual, deci de la y la x
vecini[y].push_back(x);
cost[y].push_back(-c);
idmuchie[x][y] = i;
capacitate[x][y] = 1;
}
}
void construire_graf_flux()
//construim un graf pe care putem aplica fluxul maxim de cost minim
{
sursa = 1;
destinatie = n + m + 2;
for (int i = 2;i <= n + 1;++i)
//legam sursa de nodurile din prima multime
{
vecini[sursa].push_back(i);
cost[sursa].push_back(0);
vecini[i].push_back(sursa);
cost[i].push_back(0);
capacitate[sursa][i] = 1;
}
for (int i = n + 2;i <= n + m + 1;++i)
//legam sursa de nodurile din prima multime
{
vecini[i].push_back(destinatie);
cost[i].push_back(0);
vecini[destinatie].push_back(i);
cost[destinatie].push_back(0);
capacitate[i][destinatie] = 1;
}
}
int bellmanford()
//intoarce costul drumului de ameliorare sau 0 daca nu mai exista drum de ameliorare
{
int d[MAXN];
int tata[MAXN];
bool in_coada[MAXN];
int coada[MAXN * MAXN] = {0};
for (int i = sursa;i <= destinatie;++i)
{
d[i] = INF;
tata[i] = -1;
in_coada[i] = false;
}
d[sursa] = 0;
int p = 1,q = 1;
coada[1] = sursa;
in_coada[sursa] = true;
while(p <= q)
{
int nod = coada[p];
for (unsigned int i = 0;i < vecini[nod].size();++i)
{
int vecin = vecini[nod][i];
if (vecin == destinatie)
vecin = destinatie;
int cst = cost[nod][i];
if (capacitate[nod][vecin] > flux[nod][vecin] && d[nod] + cst < d[vecin])
{
d[vecin] = d[nod] + cst;
tata[vecin] = nod;
if (!in_coada[vecin])
{
coada[++q] = vecin;
in_coada[vecin] = true;
}
}
}
++p;
in_coada[nod] = false;
}
if (d[destinatie] == INF)
return 0;
int influx = INF;
for (int i = destinatie;i != sursa;i = tata[i])
{
int x = capacitate[tata[i]][i] - flux[tata[i]][i];
if (x < influx)
influx = x;
}
for (int i = destinatie;i != sursa;i = tata[i])
{
flux[tata[i]][i] += influx;
flux[i][tata[i]] -= influx;
}
return influx * d[destinatie];
}
int nr_muchii_rasp, cost_minim;
void afisare()
{
for (int i = 2;i <= n + 1;++i)
for (int j = n + 2;j <= n + m + 2;++j)
if (capacitate[i][j] != 0 && flux[i][j] != 0)
{
++nr_muchii_rasp;
break;
}
out << nr_muchii_rasp << ' ' << cost_minim << '\n';
for (int i = 2;i <= n + 1;++i)
for (int j = n + 2;j <= n + m + 2;++j)
if (capacitate[i][j] != 0 && flux[i][j] != 0)
{
out << idmuchie[i][j] << ' ';
break;
}
out << '\n';
}
int main()
{
citire();
construire_graf_flux();
int cost_pred = -1;
while(cost_minim != cost_pred)
{
cost_pred = cost_minim;
cost_minim += bellmanford();
}
afisare();
return 0;
}