Pagini recente » Cod sursa (job #1834841) | Cod sursa (job #3274750) | Cod sursa (job #1844821) | Cod sursa (job #3147472) | Cod sursa (job #2689619)
#include <bits/stdc++.h>
using namespace std;
const int MAX = 2000000000;
const int N = 510;
int n, m, s, d;
int cost[N][N], cap[N][N], old_dist[N], dist[N], pr[N];
int aux[N];
bool vis[N];
vector <int> graph[N];
queue <int> Q;
priority_queue < pair <int, int> > S;
class InParser{
private:
FILE *fin;
char *buff;
int sp;
char read_ch(){
++sp;
if (sp == 4096){
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume){
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator>> (int &n){
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-'){
n = 0;
sgn = -1;
}
else{
n = c - '0';
}
while (isdigit(c = read_ch())){
n = n * 10 + c - '0';
}
n *= sgn;
return *this;
}
};
inline void Bellman(){
int i, node, new_dist;
for (i = 1; i <= n; ++i)
old_dist[i] = MAX;
memset(vis, 0, sizeof(vis));
old_dist[s] = 0;
Q.push(s);
vis[s] = 1;
while(not Q.empty()){
node = Q.front();
Q.pop();
for (int nei : graph[node]){
if (!cap[node][nei])
continue;
new_dist = old_dist[node] + cost[node][nei];
if (new_dist < old_dist[nei]){
old_dist[nei] = new_dist;
if (!vis[nei]){
Q.push(nei);
vis[nei] = 1;
}
}
}
vis[node] = 0;
}
}
inline int Dijkstra(){
int i, node, new_dist, curr_cost;
for (i = 1; i <= n; ++i){
pr[i] = -1;
dist[i] = MAX;
vis[i] = 0;
aux[i] = MAX;
}
S.push({0, s});
dist[s] = 0;
aux[s] = 0;
while (not S.empty()){
auto nod = S.top();
S.pop();
node = nod.second;
curr_cost = -nod.first;
if (vis[node])
continue;
vis[node] = 1;
for (int &nei: graph[node]){
if (vis[nei])
continue;
if (!cap[node][nei])
continue;
new_dist = curr_cost + cost[node][nei] + old_dist[node] - old_dist[nei];
if (new_dist < dist[nei]){
dist[nei] = new_dist;
aux[nei] = aux[node] + cost[node][nei];
pr[nei] = node;
S.push({-new_dist, nei});
}
}
}
for (i = 1; i <= n; ++i){
old_dist[i] = aux[i];
}
if (dist[d] == MAX)
return 0;
int flow = 1e9, path_cost = 0;
for (node = d; node != s; node = pr[node])
flow = min(flow, cap[pr[node]][node]);
for (node = d; node != s; node = pr[node]){
cap[pr[node]][node] -= flow;
cap[node][pr[node]] += flow;
path_cost += cost[pr[node]][node];
}
return flow * path_cost;
}
int main(){
InParser cin("fmcm.in");
ofstream cout("fmcm.out");
int i, a, b, c, z;
cin >> n >> m >> s >> d;
for (i = 1; i <= m; ++i){
cin >> a >> b >> c >> z;
graph[a].push_back(b);
graph[b].push_back(a);
cost[a][b] = z;
cost[b][a] = -z;
cap[a][b] = c;
}
Bellman();
int ans = 0, path_cost = 0;
do{
path_cost = Dijkstra();
ans += path_cost;
} while(path_cost);
cout << ans << '\n';
return 0;
}