Pagini recente » Statistici Sorin Soo (sorynsoo) | Istoria paginii utilizator/mihai.dochita | Monitorul de evaluare | Istoria paginii utilizator/alexiksm | Cod sursa (job #1962856)
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
struct Pair {
int nod, cost;
const bool operator< (const Pair &other) const {
return cost > other.cost;
}
};
const int NMAX = 351;
int n, m, source, sink;
int cap[NMAX][NMAX], cst[NMAX][NMAX];
vector<vector<int> > v;
int flw, minCostFlw;
int oldD[NMAX];
bitset<NMAX> inQueue;
int d[NMAX], realD[NMAX], t[NMAX];
priority_queue<Pair> pq;
inline void read() {
fin >> n >> m >> source >> sink;
int x, y;
v = vector<vector<int> >(n + 1);
while (m--) {
fin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
fin >> cap[x][y] >> cst[x][y];
cst[y][x] = -cst[x][y];
}
}
inline void bellmanFord() {
for (int i = 1; i <= n; ++i)
oldD[i] = 0x3f3f3f3f;
oldD[source] = 0;
queue<int> q;
int node;
for (q.push(source), inQueue[source] = 1; q.size(); q.pop()) {
node = q.front();
inQueue[node] = 0;
for (const int& other: v[node]) {
if (cap[node][other]) {
if (oldD[node] + cst[node][other] >= oldD[other])
continue;
oldD[other] = oldD[node] + cst[node][other];
if (inQueue[other])
continue;
inQueue[other] = 1;
q.push(other);
}
}
}
}
inline bool dijkstra() {
for (int i = 1; i <= n; ++i)
d[i] = 0x3f3f3f3f;
d[source] = 0;
realD[source] = 0;
pq.push({source, d[source]});
int x, dx;
int newD;
while (pq.size()) {
x = pq.top().nod, dx = pq.top().cost;
pq.pop();
if (d[x] != dx)
continue;
for (const int& y: v[x]) {
if (cap[x][y]) {
newD = d[x] + cst[x][y] + oldD[x] - oldD[y];
if (newD < d[y]) {
d[y] = newD;
realD[y] = realD[x] + cst[x][y];
t[y] = x;
pq.push({y, d[y]});
}
}
}
}
for (int i = 1; i <= n; ++i)
oldD[i] = realD[i];
if (d[sink] == 0x3f3f3f3f)
return false;
int mn = 0x3f3f3f3f, currCost = 0;
for (int i = sink; i != source; i = t[i]) {
mn = min(mn, cap[t[i]][i]);
currCost += cst[t[i]][i];
}
flw += mn;
minCostFlw += mn * realD[sink];
for (int i = sink; i != source; i = t[i]) {
cap[t[i]][i] -= mn;
cap[i][t[i]] += mn;
}
return 1;
}
int main()
{
read();
bellmanFord();
while (dijkstra());
fout << minCostFlw;
fin.close();
fout.close();
return 0;
}