Pagini recente » Cod sursa (job #1898359) | Cod sursa (job #2547040) | Cod sursa (job #1531317) | Cod sursa (job #1009827) | Cod sursa (job #831278)
Cod sursa(job #831278)
#include <cstdio>
#include <vector>
const int MAX_SIZE(351);
const int MAX_VALUE(1 << 30);
const int MAX_CAPACITY(10000);
int n, m, source, sink, min_cost;
long long maxflow;
int cost [MAX_SIZE] [MAX_SIZE];
int capacity [MAX_SIZE] [MAX_SIZE];
int min_path [MAX_SIZE];
int heap [MAX_SIZE], heap_size;
int heap_position [MAX_SIZE];
int queue [MAX_SIZE * MAX_SIZE];
bool in_queue [MAX_SIZE];
int pred [MAX_SIZE];
std::vector<int> graph [MAX_SIZE];
inline void read (void)
{
std::freopen("fmcm.in","r",stdin);
std::scanf("%d %d %d %d",&n,&m,&source,&sink);
int x, y, c, z;
for (int counter(0) ; counter < m ; ++counter)
{
std::scanf("%d %d %d %d",&x,&y,&c,&z);
graph[x].push_back(y);
graph[y].push_back(x);
capacity[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
}
std::fclose(stdin);
}
inline void print (void)
{
std::freopen("fmcm.out","w",stdout);
std::printf("%lld\n",maxflow);
std::fclose(stdout);
}
inline void BellmanFord (void)
{
int index, size;
for (index = 1 ; index <= n ; ++index)
min_path[index] = MAX_VALUE;
min_path[source] = 0;
*queue = source;
in_queue[source] = true;
int *pop(queue), *push(queue + 1), vertex, neighbor;
while (pop < push)
{
vertex = *pop;
++pop;
for (index = 0, size = graph[vertex].size() ; index < size ; ++index)
if (capacity[vertex][graph[vertex][index]] && min_path[vertex] + cost[vertex][graph[vertex][index]] < min_path[graph[vertex][index]])
{
neighbor = graph[vertex][index];
min_path[neighbor] = min_path[vertex] + cost[vertex][neighbor];
if (!in_queue[neighbor])
{
*push = neighbor;
++push;
in_queue[neighbor] = true;
}
}
in_queue[vertex] = false;
}
min_cost = min_path[sink];
}
inline void initialize (void)
{
int index, vertex, size;
for (index = 1 ; index <= n ; ++index)
if (min_path[index] != MAX_VALUE)
for (vertex = 0, size = graph[index].size() ; vertex < size ; ++vertex)
if (min_path[graph[index][vertex]] != MAX_VALUE)
cost[index][graph[index][vertex]] += min_path[index] - min_path[graph[index][vertex]];
for (index = 1 ; index <= n ; ++index)
{
min_path[index] = MAX_VALUE;
heap[index - 1] = index;
heap_position[index] = index - 1;
}
min_path[source] = 0;
if (source > 1)
{
*heap = source;
heap_position[source] = 0;
heap[source - 1] = 1;
heap_position[1] = source - 1;
}
heap_size = n;
}
inline void swap (int &a, int &b)
{
int temp(a);
a = b;
b = temp;
}
inline void up (int index)
{
if (index)
{
int father((index - 1) >> 1), vertex(heap[index]);
while (true)
{
if (min_path[vertex] < min_path[heap[father]])
{
heap[index] = heap[father];
swap(heap_position[heap[father]],heap_position[vertex]);
}
else
break;
index = father;
if (father)
{
--father;
father >>= 1;
}
else
break;
}
heap[index] = vertex;
}
}
inline void down (int index)
{
int left((index << 1) + 1), right(left + 1), smallest;
while (true)
{
if (left < heap_size && min_path[heap[left]] < min_path[heap[index]])
smallest = left;
else
smallest = index;
if (right < heap_size && min_path[heap[right]] < min_path[heap[smallest]])
smallest = right;
if (smallest == index)
break;
swap(heap_position[heap[smallest]],heap_position[heap[index]]);
swap(heap[index],heap[smallest]);
index = smallest;
left = (index << 1) + 1;
right = left + 1;
}
}
inline void pop (void)
{
--heap_size;
*heap = heap[heap_size];
down(0);
}
inline void Dijkstra (void)
{
initialize();
int vertex, neighbor;
int index, size;
while (heap_size)
{
vertex = *heap;
pop();
for (index = 0, size = graph[vertex].size() ; index < size ; ++index)
if (capacity[vertex][graph[vertex][index]] && min_path[vertex] + cost[vertex][graph[vertex][index]] < min_path[graph[vertex][index]])
{
neighbor = graph[vertex][index];
min_path[neighbor] = min_path[vertex] + cost[vertex][neighbor];
pred[neighbor] = vertex;
up(heap_position[neighbor]);
}
}
}
inline void FordFulkerson (void)
{
int vertex, path_capacity;
while (true)
{
Dijkstra();
if (min_path[sink] == MAX_VALUE)
break;
min_cost += min_path[sink];
path_capacity = MAX_CAPACITY;
for (vertex = sink ; vertex != source ; vertex = pred[vertex])
if (capacity[pred[vertex]][vertex] < path_capacity)
path_capacity = capacity[pred[vertex]][vertex];
for (vertex = sink ; vertex != source ; vertex = pred[vertex])
{
capacity[pred[vertex]][vertex] -= path_capacity;
capacity[vertex][pred[vertex]] += path_capacity;
}
maxflow += min_cost * path_capacity;
}
}
int main (void)
{
read();
BellmanFord();
FordFulkerson();
print();
}