Pagini recente » Cod sursa (job #3147054) | Cod sursa (job #145568) | Cod sursa (job #1457340) | Cod sursa (job #1382925) | Cod sursa (job #1669196)
#include <iostream>
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");
const int nmax = 355;
const int oo = 2e9;
vector <int> g[nmax];
int cap[nmax][nmax], cost[nmax][nmax], f[nmax][nmax], dady[nmax];
int old_dist[nmax], real_dist[nmax], dist[nmax], n, m;
void bellman(int source, int dest) {
vector <int> :: iterator son;
queue <int> q;
bitset <nmax> viz;
int dad;
fill(old_dist+1, old_dist+n+1, oo);
old_dist[source]=0;
q.push(source);
while(!q.empty()){
dad=q.front();
viz[dad]=false;
q.pop();
for(son=g[dad].begin(); son!=g[dad].end(); son++)
if(old_dist[*son] > old_dist[dad]+cost[dad][*son] && cap[dad][*son]){
old_dist[*son]=old_dist[dad]+cost[dad][*son];
if(viz[*son]==false){
viz[*son]=true;
q.push(*son);
}
}
}
}
bool dijkstra(int source, int dest) {
priority_queue <pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > heap;
vector <int> :: iterator son;
int dad, new_dist, cst;
fill(dist+1, dist+n+1, oo);
fill(real_dist+1, real_dist+n+1, oo);
dist[source]=real_dist[source]=0;
heap.push({0, source});
while(!heap.empty()) {
cst=heap.top().first;
dad=heap.top().second;
heap.pop();
if(cst!=dist[dad]) continue;
for(son=g[dad].begin(); son!=g[dad].end(); son++)
if(cap[dad][*son] > f[dad][*son]) {
new_dist=dist[dad]+cost[dad][*son]+old_dist[dad]-old_dist[*son];
if(real_dist[*son] > new_dist) {
dady[*son]=dad;
dist[*son]=new_dist;
real_dist[*son]=real_dist[dad]+cost[dad][*son];
heap.push({dist[*son], *son});
}
}
}
for(int i=1; i<=n; i++)
old_dist[i]=real_dist[i];
if(dist[dest]==oo) return false;
return true;
}
void Max_Flow_Min_Cost(int source, int dest) {
int max_flow=0, flow, node;
bellman(source, dest);
while(dijkstra(source, dest)) {
flow=oo;
for(node=dest; node!=source; node=dady[node]) {
flow=min(flow, cap[dady[node]][node]-f[dady[node]][node]);
}
for(node=dest; node!=source; node=dady[node]) {
f[dady[node]][node]+=flow;
f[node][dady[node]]-=flow;
}
max_flow=flow*dist[dest];
}
fout << max_flow;
}
int main() {
ios_base::sync_with_stdio(false);
int x, y, c, cs, i, source, dest;
fin >> n >> m >> source >> dest;
for(i=1; i<=m; i++) {
fin >> x >> y >> c >> cs;
g[x].push_back(y);
g[y].push_back(x);
cap[x][y]=c;
cost[x][y]=cs;
cost[y][x]=-cs;
}
Max_Flow_Min_Cost(source, dest);
fin.close();
fout.close();
return 0;
}