Pagini recente » Cod sursa (job #2093169) | Cod sursa (job #1837929) | Cod sursa (job #1794179) | Cod sursa (job #2940322) | Cod sursa (job #935144)
Cod sursa(job #935144)
#include <fstream>
#include <vector>
#include <queue>
#define nmax 360
#define oo (1<<30)
#define Neighbor Graph[Node][i]
using namespace std;
vector <int> Graph[nmax];
int N, M, Source, Sink, CostMaxFlow, Distance[nmax];
int Capacity[nmax][nmax], Cost[nmax][nmax], Father[nmax];
bool inQueue[nmax];
class heap {
#define hmax nmax;
#define father(node) (node>>1)
#define leftSon(node) (node<<1)
#define rightSon(node) ((node<<1)|1)
#define compare(a, b) ( Distance[H[a]] < Distance[H[b]] )
#define compareMin(a, b) compare(a, b)
#define comapreMax(a, b) compare(b, a)
public:
int Top,H[nmax],Index[nmax];
public:
heap() {
Top = 0;
}
void precolate(int Node) {
while( Node > 1 && compareMin(Node, father(Node)) ) {
swap(H[Node], H[father(Node)]);
swap(Index[H[Node]], Index[H[father(Node)]]);
Node = father(Node);
}
}
void sift(int Node) {
int Son;
do {
Son = 0;
if( leftSon(Node) <= this -> size() ) {
Son = leftSon(Node);
if( rightSon(Node) <= this -> size() && compareMin(rightSon(Node), Son) )
Son = rightSon(Node);
if( compareMin(Node, Son) )
Son = 0;
}
if( Son ) {
swap(H[Node], H[Son]);
swap(Index[H[Node]], Index[H[Son]]);
Node = Son;
}
} while( Son );
}
void push(int Node, int Value) {
H[ ++Top ] = Node;
Index[Node] = Top;
Distance[Node] = Value;
this -> precolate(Top);
}
void pop() {
H[1] = H[ Top-- ];
this -> sift(1);
}
void update(int Node, int Value) {
int Aux = Distance[Node];
Distance[Node] = Value;
if( Aux > Distance[Node] )
this -> precolate( Index[Node] );
else
this -> sift( Index[Node] );
}
int size() {
return Top;
}
bool empty() {
return ( Top == 0);
}
int top() {
return H[1];
}
};
void InitialiseDijkstra() {
int i, Node;
for(Node = 1; Node <= N; Node++)
for(i = 0; i < Graph[Node].size(); i++)
if( Distance[Node] != oo && Distance[Neighbor] != oo )
Cost[Node][Neighbor] += Distance[Node] - Distance[Neighbor];
}
bool Dijkstra(int Source, int Sink) {
int i, Node;
heap Heap;
InitialiseDijkstra();
for(Node = 1; Node <= N; Node++)
Heap.push(Node, oo);
Heap.update(Source, 0);
while( !Heap.empty() ) {
Node = Heap.top();
Heap.pop();
for(i = 0; i < Graph[Node].size(); i++)
if( Capacity[Node][Neighbor] > 0 && Distance[Neighbor] > Distance[Node] + Cost[Node][Neighbor] ) {
Father[Neighbor] = Node;
Heap.update(Neighbor, Distance[Node] + Cost[Node][Neighbor] );
}
}
return ( Distance[Sink] != oo );
}
int BellmanFord(int Source, int Sink) {
int i, Node;
queue <int> Queue;
for(i = 1; i <= N; i++)
Distance[i] = oo;
Queue.push(Source);
Distance[Source] = 0;
while(!Queue.empty()) {
Node = Queue.front();
Queue.pop();
inQueue[Node] = false;
for(i = 0; i < Graph[Node].size(); i++)
if( Capacity[Node][Neighbor] > 0 && Distance[Neighbor] > Distance[Node] + Cost[Node][Neighbor] ) {
Distance[Neighbor] = Distance[Node] + Cost[Node][Neighbor];
if( !inQueue[Neighbor] ) {
Queue.push(Neighbor);
inQueue[Neighbor] = true;
}
}
}
return Distance[Sink];
}
void Solve() {
int i, Sum, maxFlow, Node;
Sum = BellmanFord(Source, Sink);
while( Dijkstra(Source, Sink) ) {
maxFlow = oo;
for(Node = Sink; Node != Source; Node = Father[Node])
maxFlow = min(maxFlow, Capacity[Father[Node]][Node]);
for(Node = Sink; Node != Source; Node = Father[Node]) {
Capacity[Father[Node]][Node] -= maxFlow;
Capacity[Node][Father[Node]] += maxFlow;
}
Sum += Distance[Sink];
CostMaxFlow += Sum * maxFlow;
}
}
void Read() {
int i, x, y, capacity, cost;
ifstream in("fmcm.in");
in>>N>>M>>Source>>Sink;
for(i = 1; i <= M; i++) {
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<<CostMaxFlow<<'\n';
out.close();
}
int main() {
Read();
Solve();
Write();
return 0;
}