Pagini recente » Cod sursa (job #1742202) | Cod sursa (job #3167998) | Cod sursa (job #2523188) | Cod sursa (job #2646391) | Cod sursa (job #2958810)
#include<iostream>
#include<deque>
#include<algorithm>
#include<vector>
#include<fstream>
#include<queue>
using namespace std;
ifstream in("fmcm.in");
ofstream out("fmcm.out");
const int mx = 400;
const int inf = 1e9;
struct node{
int index,distance;
};
struct flow_result {
int flow, cost;
};
struct compare{
bool operator ()(const node&a, const node&b){
return a.distance>b.distance;
}
};
int n,m,s,t;
int capacity[mx][mx];
// cost[i][j] - the cost of the edge (i,j)
int cost[mx][mx];
// dist[i] = the minimum distance from s to i
int old_dist[mx];
int dist[mx];
int parent[mx];
bool in_queue[mx];
vector<int> g[mx];
void read(){
in>>n>>m>>s>>t;
int a,b,c,d;
for(int i=0;i<m;i++){
in>>a>>b>>c>>d;
cost[a][b] = d;
cost[b][a] = -d;
capacity[a][b] = c;
capacity[b][a] = 0;
g[a].push_back(b);
g[b].push_back(a);
}
}
void bf(){
for(int i=1;i<=n;i++){
old_dist[i] = inf;
}
old_dist[s] = 0;
queue<int> q;
q.push(s);
in_queue[s] = true;
while(!q.empty()){
int here = q.front();
q.pop();
in_queue[here] = false;
for(int k:g[here]){
if(capacity[here][k] == 0)
continue;
if(old_dist[here] + cost[here][k] < old_dist[k]){
old_dist[k] = old_dist[here] + cost[here][k];
if(!in_queue[k]){
q.push(k);
in_queue[k] = true;
}
}
}
}
}
flow_result flow(){
for(int i=1;i<=n;i++){
parent[i] = -1;
dist[i] = inf;
}
priority_queue<node,vector<node>,compare> q;
q.push({s,0});
dist[s] = 0;
parent[s] = 0;
while(!q.empty()){
node here = q.top();
q.pop();
if(here.distance != dist[here.index])
continue;
for(int k:g[here.index]){
if(capacity[here.index][k] == 0)
continue;
int distance = old_dist[here.index] + cost[here.index][k] - old_dist[k];
int new_dist = here.distance + distance;
if(new_dist < dist[k]){
dist[k] = new_dist;
parent[k] = here.index;
q.push({k,new_dist});
}
}
}
int c= 0;
int flow = inf;
if(parent[t] == -1)
return {0,0};
int now = t;
while(now!=s){
flow = min(flow, capacity[parent[now]][now]);
c += cost[parent[now]][now];
now = parent[now];
}
now = t;
while(now!=s){
capacity[parent[now]][now] -= flow;
capacity[now][parent[now]] += flow;
now = parent[now];
}
for(int i=1;i<=n;i++){
old_dist[i] = dist[i];
}
return {flow, c*flow};
}
void solve(){
bf();
flow_result current_flow;
int total_cost = 0;
do{
current_flow = flow();
total_cost +=current_flow.cost;
}
while(current_flow.flow);
out<<total_cost<<endl;
}
int main(){
read();
solve();
return 0;
}