Pagini recente » Cod sursa (job #615676) | Cod sursa (job #1227266) | Cod sursa (job #1468344) | Cod sursa (job #2757782) | Cod sursa (job #1022198)
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <limits.h>
using namespace std;
typedef struct node{
int index;
int cost;
} NODE;
int n,m,s,d;
vector<int> adjacencyList[351];
int flow[351][351];
int capacities[351][351];
int costs[351][351];
int visited[351];
int prevv[351];
int originalCosts[351];
int smallestDistances[351];
int newSmallestDistances[351];
void relax(int from, int to){
if (smallestDistances[from] != INT_MAX
&& (smallestDistances[from] + costs[from][to]) < smallestDistances[to]){
smallestDistances[to] = smallestDistances[from] + costs[from][to];
}
}
void bellmanFord(){
for (int i=1; i<=n; i++){
smallestDistances[i] = INT_MAX;
}
smallestDistances[s]=0;
for (int i=0; i<n-1; i++){
//take all edges
for (int from=1; from <= n; from++){
for (int toIndex=0; toIndex< adjacencyList[from].size(); toIndex++){
int to = adjacencyList[from][toIndex];
if (capacities[from][to] - flow[from][to] > 0){
relax(from, to);
}
}
}
}
}
struct cmp_node{
bool operator() (const NODE &x, const NODE &y){
return x.cost > y.cost;
}
};
int dijkstra(int sourceNode){
priority_queue<NODE, vector<NODE>, cmp_node> q;
int dijkstraCosts[351];
int visited[351];
for (int i=0; i<=n; i++){
visited[i] = 0;
dijkstraCosts[i] = INT_MAX;
}
NODE n;
n.index = sourceNode;
n.cost = 0;
dijkstraCosts[sourceNode] = 0;
originalCosts[sourceNode] = 0;
q.push(n);
while (!q.empty()){
NODE currentNode = q.top();
q.pop();
if (!visited[currentNode.index]){
visited[currentNode.index] = 1;
for (int i=0; i< adjacencyList[currentNode.index].size(); i++){
int nextNode = adjacencyList[currentNode.index][i];
if (!visited[nextNode]
&& capacities[currentNode.index][nextNode] - flow[currentNode.index][nextNode] > 0){
int edgeCost = costs[currentNode.index][nextNode] +
smallestDistances[currentNode.index] - smallestDistances[nextNode];
int costForNewNode = dijkstraCosts[currentNode.index] + edgeCost;
if (costForNewNode < dijkstraCosts[nextNode]){
dijkstraCosts[nextNode] = costForNewNode;
originalCosts[nextNode] = originalCosts[currentNode.index] + costs[currentNode.index][nextNode];
prevv[nextNode] = currentNode.index;
NODE n2;
n2.index = nextNode;
n2.cost = costForNewNode;
q.push(n2);
}
}
}
}
}
return visited[d];
}
int main()
{
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
scanf("%d %d %d %d", &n, &m, &s, &d);
int from, to, capacity, cost;
for (int i=0; i<m; i++){
scanf("%d %d %d %d", &from, &to, &capacity, &cost);
adjacencyList[from].push_back(to);
adjacencyList[to].push_back(from);
capacities[from][to] = capacity;
costs[from][to] = cost;
costs[to][from] = (-1)*cost;
}
bellmanFord();
//work
long long sum = 0;
while (dijkstra(s)){
for (int i=1; i<=n; i++){
smallestDistances[i] = originalCosts[i];
}
int currentNode = d;
int minn = INT_MAX;
while (currentNode != s){
if (minn > capacities[prevv[currentNode]][currentNode] - flow[prevv[currentNode]][currentNode]){
minn = capacities[prevv[currentNode]][currentNode] - flow[prevv[currentNode]][currentNode];
}
currentNode = prevv[currentNode];
}
currentNode = d;
while (currentNode != s){
flow[prevv[currentNode]][currentNode] += minn;
flow[currentNode][prevv[currentNode]] -= minn;
currentNode = prevv[currentNode];
}
sum += minn*smallestDistances[d];
}
printf("%lld", sum);
return 0;
}