Pagini recente » Cod sursa (job #942718) | Cod sursa (job #2809744) | Cod sursa (job #1442361) | Cod sursa (job #1972746) | Cod sursa (job #831149)
Cod sursa(job #831149)
#include <cstdio>
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];
struct edge
{
int node;
struct edge *next;
} *graph [MAX_SIZE];
inline void add (int x, int y)
{
struct edge *new_edge(new struct edge);
new_edge->node = y;
new_edge->next = graph[x];
graph[x] = new_edge;
}
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);
add(x,y);
add(y,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)
{
for (int 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;
struct edge *iterator;
while (pop < push)
{
vertex = *pop;
++pop;
for (iterator = graph[vertex] ; iterator ; iterator = iterator->next)
if (capacity[vertex][iterator->node] && min_path[vertex] + cost[vertex][iterator->node] < min_path[iterator->node])
{
neighbor = iterator->node;
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;
struct edge *iterator;
for (index = 1 ; index <= n ; ++index)
if (min_path[index] != MAX_VALUE)
for (iterator = graph[index] ; iterator ; iterator = iterator->next)
if (min_path[iterator->node] != MAX_VALUE)
cost[index][iterator->node] += min_path[index] - min_path[iterator->node];
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;
struct edge *iterator;
while (heap_size)
{
vertex = *heap;
pop();
for (iterator = graph[vertex] ; iterator ; iterator = iterator->next)
if (capacity[vertex][iterator->node] && min_path[vertex] + cost[vertex][iterator->node] < min_path[iterator->node])
{
neighbor = iterator->node;
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();
}