Pagini recente » Cod sursa (job #1683787) | Cod sursa (job #1446045) | Cod sursa (job #1042023) | Cod sursa (job #1572874) | Cod sursa (job #1334095)
#include <fstream>
#include <vector>
#include <queue>
#define Nmax 352
#define oo (1 << 30)
#define neighbour Graph[node][i]
using namespace std;
vector <int> Graph[Nmax];
int N, minCost, Source, Destination, Cost[Nmax][Nmax], Capacity[Nmax][Nmax], Father[Nmax];
bool inQueue[Nmax];
class priorityQueue {
#define root 1
#define father (node >> 1)
#define leftSon (node << 1)
#define rightSon ((node << 1) | 1)
#define compare(a, b) (A[Heap[a]] < A[Heap[b]])
private:
int size, Heap[Nmax], Location[Nmax];
public:
int A[Nmax];
priorityQueue() {
size = 0;
}
void insert(int index, int value) {
A[index] = value;
Heap[++size] = index;
Location[index] = size;
up(size);
}
void update(int index, int value) {
A[index] = value;
up(Location[index]);
}
void pop() {
Heap[1] = Heap[size--];
Location[Heap[1]] = 1;
down(1);
}
inline int operator[](int index) {
return A[index];
}
int front() {
return Heap[1];
}
bool empty() {
return (size == 0);
}
private:
void up(int node) {
while(node != root && compare(node, father)) {
swap(Heap[node], Heap[father]);
swap(Location[Heap[node]], Location[Heap[father]]);
node = father;
}
}
void down(int node) {
int son;
do {
son = 0;
if(leftSon <= size) {
son = leftSon;
if(rightSon <= size && compare(rightSon, son))
son = rightSon;
if(compare(node, son))
son = 0;
}
if(son != 0) {
swap(Heap[node], Heap[son]);
swap(Location[Heap[node]], Location[Heap[son]]);
node = son;
}
} while(son);
}
} pq;
int BellmanFord() {
int i, node;
queue <int> Queue;
for(i = 1; i <= N; i++)
pq.A[i] = oo;
pq.A[Source] = 0;
Queue.push(Source);
inQueue[Source] = true;
while(!Queue.empty()) {
node = Queue.front();
Queue.pop();
inQueue[node] = false;
for(i = 0; i < Graph[node].size(); i++)
if(Capacity[node][neighbour] > 0 && pq[neighbour] > pq[node] + Cost[node][neighbour]) {
pq.A[neighbour] = pq[node] + Cost[node][neighbour];
if(!inQueue[neighbour]) {
Queue.push(neighbour);
inQueue[neighbour] = true;
}
}
}
return pq[Destination];
}
bool Dijkstra() {
int i, node;
for(node = 1; node <= N; node++)
for(i = 0; i < Graph[node].size(); i++)
if(pq[node] != oo && pq[neighbour] != oo)
Cost[node][neighbour] += pq[node] - pq[neighbour];
for(node = 1; node <= N; node++)
pq.insert(node, oo);
pq.update(Source, 0);
while(!pq.empty()) {
node = pq.front();
pq.pop();
for(i = 0; i < Graph[node].size(); i++)
if(Capacity[node][neighbour] > 0 && pq[neighbour] > pq[node] + Cost[node][neighbour]) {
pq.update(neighbour, pq[node] + Cost[node][neighbour]);
Father[neighbour] = node;
}
}
return (pq[Destination] != oo);
}
void Solve() {
int cost, node, maxFlow;
cost = BellmanFord();
while(Dijkstra()) {
maxFlow = oo;
for(node = Destination; node != Source; node = Father[node])
maxFlow = min(maxFlow, Capacity[Father[node]][node]);
for(node = Destination; node != Source; node = Father[node]) {
Capacity[Father[node]][node] -= maxFlow;
Capacity[node][Father[node]] += maxFlow;
}
cost += pq[Destination];
minCost += maxFlow * cost;
}
}
void Read() {
int x, y, cost, capacity, M;
ifstream in("fmcm.in");
in >> N >> M >> Source >> Destination;
while(M--) {
in >> x >> y >> capacity >> cost;
Graph[x].push_back(y);
Graph[y].push_back(x);
Cost[x][y] = cost;
Cost[y][x] = -cost;
Capacity[x][y] = capacity;
}
in.close();
}
void Write() {
ofstream out("fmcm.out");
out << minCost << '\n';
out.close();
}
int main() {
Read();
Solve();
Write();
return 0;
}