Pagini recente » Cod sursa (job #2387245) | Cod sursa (job #3226399) | Cod sursa (job #3135065) | Cod sursa (job #1488619) | Cod sursa (job #3258471)
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
const int maxn = 302, inf = 0x3f3f3f3f;
int n, m, s, d;
int cap[maxn][maxn], cst[maxn][maxn];
vector<int> v[maxn];
queue<int> q;
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;
vector<pair<int, int> > muchii;
int originalDistance[maxn], dist[maxn], realDistance[maxn], p[maxn], indice[maxn][maxn];
bool inQ[maxn];
int finalCost, finalFlow;
void bellmanford() {
memset(originalDistance, inf, sizeof(originalDistance));
originalDistance[s] = 0;
q.push(s);
inQ[s] = true;
while(!q.empty()) {
int x = q.front();
inQ[x] = false;
for(auto u : v[x]) {
if(cap[x][u]) {
if(originalDistance[x] + cst[x][u] < originalDistance[u]) {
originalDistance[u] = originalDistance[x] + cst[x][u];
if(inQ[u] == false) {
inQ[u] = true;
q.push(u);
}
}
}
}
q.pop();
}
}
bool dijkstra() {
// cout << "entered dijkstra\n";
memset(dist, inf, sizeof(dist));
dist[s] = 0; realDistance[s] = 0;
pq.push({dist[s], s});
while(!pq.empty()) {
int currCost = pq.top().first;
int currNode = pq.top().second;
pq.pop();
if(dist[currNode] != currCost) // eu pun acelasi nod de mai multe ori in pq daca e nevoie
continue; // dar il iau doar atunci cand distanta e cea mai mica
for(auto u : v[currNode]) {
if(cap[currNode][u]) {
int newDist = dist[currNode] + cst[currNode][u] + originalDistance[currNode] - originalDistance[u];
// cout << "cost from " << currNode << " to " << u << " is " << cst[currNode][u] + originalDistance[currNode] - originalDistance[u] << '\n';
if(newDist < dist[u]) {
dist[u] = newDist;
realDistance[u] = realDistance[currNode] + cst[currNode][u];
p[u] = currNode;
pq.push({dist[u], u});
}
}
}
}
// cout << "old distance: ";
// for(int i = 1; i <= n; i ++) {
// cout << originalDistance[i] << ' ';
// }
// cout << "\nreal distance: ";
// for(int i = 1; i <= n; i ++) {
// cout << realDistance[i] << ' ';
// }
// cout << '\n';
memcpy(originalDistance, realDistance, sizeof(originalDistance));
if(dist[d] == inf) // daca nu a facut drum pana la destinatie, nu s-a mai imbunatatit,
return false; // deci ne oprim
int minim = inf, curCst = 0;
for(int i = d; i != s; i = p[i]) {
minim = min(minim, cap[p[i]][i]);
curCst += cst[p[i]][i];
}
finalFlow += minim;
finalCost += curCst * minim; // sau minim * realDistance[d]
for(int i = d; i != s; i = p[i]) {
cap[p[i]][i] -= minim;
cap[i][p[i]] += minim;
}
return true;
}
int main()
{
int x, y, e;
// fin >> n >> m >> s >> d;
//
// while(m --) {
// fin >> x >> y;
// fin >> cap[x][y] >> cst[x][y];
// cst[y][x] = -cst[x][y];
// v[x].push_back(y);
// v[y].push_back(x);
// }
fin >> n >> m;
fin >> e;
// int i = 1;
while(e --) {
fin >> x >> y;
y += n;
muchii.push_back({x, y});
// indice[x][y] = i;
fin >> cst[x][y];
cst[y][x] = -cst[x][y];
cap[x][y] = 1;
v[x].push_back(y);
v[y].push_back(x);
// i ++;
}
// n+m+1 -> sursa
// n+m+1 -> destinatia
s = n + m + 1;
d = n + m + 2;
for(int i = 1; i <= n; i ++) {
v[s].push_back(i);
v[i].push_back(s);
cst[i][s] = 0;
cst[s][i] = 0;
cap[s][i] = 1;
}
for(int i = n + 1; i <= n + m; i ++) {
v[i].push_back(d);
v[d].push_back(i);
cst[i][d] = 0;
cst[d][i] = 0;
cap[i][d] = 1;
}
n = n + m + 2;
bellmanford();
while(dijkstra());
fout << finalFlow << ' ' << finalCost << '\n';
int i = 1;
for(auto muchie : muchii) {
if(cap[muchie.first][muchie.second] == 0)
fout << i << ' ';
i ++;
}
fout << '\n';
fin.close();
fout.close();
return 0;
}