Pagini recente » Cod sursa (job #3278446) | Cod sursa (job #3279166) | Cod sursa (job #3289506) | Cod sursa (job #3269605) | Cod sursa (job #3193593)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream f("cc.in");
ofstream g("cc.out");
int main()
{
int n, suma = 0;
f >> n;
int last = 2*n+1;
vector<vector<int>> adj(last + 1, vector <int>()); // lista de adiacenta - pt bfs
vector<vector<int>> cost(last + 1, vector <int>(last + 1, 0));
vector<vector<int>> cap(last + 1, vector <int>(last + 1, 0));
vector<vector<int>> flux(last + 1, vector <int>(last + 1, 0));
for (int e = 1; e <= n; e++)
for (int c = n + 1; c <= 2 * n; c++)
{
int cst;
f >> cst;
cost[e][c] = cst;
cost[c][e] = -cst; // in caz ca trebuie sa ne intoarcem
adj[e].push_back(c);
adj[c].push_back(e);
cap[e][c] = 1;
}
for (int e = 1; e <= n; e++)
{
adj[e].push_back(0);
adj[0].push_back(e);
cap[0][e] = 1;
}
for (int c = n + 1; c <= 2 * n; c++)
{
adj[c].push_back(last);
adj[last].push_back(c);
cap[c][last] = 1;
}
//bellman ford
bool drum = true;
while(drum)
{
drum = false;
queue <int> q;
vector <int> parinte(last + 1); // tinem parintele fiecarui nod, daca muchia intoarce flux => -parinte
vector <int> cost_temp(last + 1, INT_MAX); // costuri pt bellman-ford
for (int i = 0; i <= last; i++)
parinte[i] = i;
q.push(0);
cost_temp[0] = 0;
while (!q.empty())
{
int nod = q.front();
q.pop();
for (int i = 0; i < adj[nod].size(); i++)
{
int vecin = adj[nod][i];
if (cap[nod][vecin] > flux[nod][vecin] && cost_temp[vecin] > cost_temp[nod] + cost[nod][vecin])
{
q.push(vecin);
parinte[vecin] = nod;
cost_temp[vecin] = cost_temp[nod] + cost[nod][vecin];
if (vecin == last) // am ajuns la destinatie
{
drum = true;
break;
}
}
}
}
// daca avem drum
if (drum)
{
// parcurgem invers
int nod = last;
int flux_max = INT_MAX;
while (nod != 0)
{
int tata = parinte[nod];
flux_max = min(flux_max,cap[tata][nod] - flux[tata][nod]);
nod = tata;
}
nod = last;
while (nod != 0)
{
int tata = parinte[nod];
flux[tata][nod] += flux_max;
flux[nod][tata] -= flux_max;
nod = tata;
}
}
}
//ce muchii am folosit pentru costul lor
for (int e = 1; e <= n; e++)
for (int c = n + 1; c <= 2 * n; c++)
if (flux[e][c])
{
suma += cost[e][c];
continue;
}
g << suma;
return 0;
}