Pagini recente » Cod sursa (job #269813) | Cod sursa (job #1274223) | Cod sursa (job #948727) | Cod sursa (job #2948015) | Cod sursa (job #2807882)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <long double, pii> muchie;
const ll NMAX = 351;
const ll VMAX = 21;
const ll INF = (1LL << 55);
const ll MOD = 998244353;
const ll BLOCK = 318;
const ll base = 31;
const ll nr_of_bits = 30;
vector <int> v[NMAX];
struct edge {
int from, to, cap, cost;
} edges[25001];
int cnt = 0, s, d, n, viz[NMAX];
int dist[NMAX], last[NMAX], distt[NMAX], distn[NMAX];
void addEdge(int a, int b, int c, int cost) {
edges[++cnt] = {a, b, c, cost};
v[a].push_back(cnt);
edges[++cnt] = {b, a, 0, -cost};
v[b].push_back(cnt);
}
int invers(int x) {
if(x % 2)
return (x + 1);
return (x - 1);
}
void bellman() {
for(int i = 1; i <= n; i++) {
viz[i] = 0, distt[i] = 2e9;
last[i] = 0;
}
queue <int> pq;
pq.push(s);
viz[s] = 1;
distt[s] = 0;
while(pq.size()) {
int node = pq.front();
pq.pop();
viz[node] = 0;
for(auto x : v[node]) {
if(!edges[x].cap)
continue;
int to = edges[x].to;
int cost = edges[x].cost;
if(distt[node] + cost < distt[to]) {
distt[to] = distt[node] + cost;
last[to] = x;
if(!viz[to]) {
pq.push(to);
viz[to] = 1;
}
}
}
}
}
bool Dijkstra(){
for(ll i = 1; i <= n; i++){
viz[i] = 0, dist[i] = 2e9, distn[i] = 2e9;
last[i] = 0;
}
priority_queue <pii> pq;
pq.push({0, s});
dist[s] = 0;
distn[s] = 0;
while(pq.size()){
while(pq.size() && viz[pq.top().second])
pq.pop();
if(!pq.size())
continue;
ll node = pq.top().second;
pq.pop();
viz[node] = 1;
for(auto x : v[node]){
if(!edges[x].cap)
continue;
ll to = edges[x].to;
ll cost = edges[x].cost + distt[node] - distt[to];
if(dist[node] + cost < dist[to]){
dist[to] = dist[node] + cost;
distn[to] = distn[node] + edges[x].cost;
pq.push({-dist[to], to});
last[to] = x;
}
}
}
for(int i = 1; i <= n; i++)
distt[i] = distn[i];
if(viz[d])
return 1;
return 0;
}
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 = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
ll flow() {
ll sol = 0;
while(Dijkstra()) {
int minim = 2e9;
int node = last[d];
while(node != 0) {
minim = min(1LL * minim, 1LL * edges[node].cap);
node = last[edges[node].from];
}
sol += 1LL * minim * distt[d];
node = last[d];
while(node != 0) {
edges[node].cap -= minim;
edges[invers(node)].cap += minim;
node = last[edges[node].from];
}
}
return sol;
}
int main() {
InParser cin("fmcm.in");
ofstream cout("fmcm.out");
int m, i;
cin >> n >> m >> s >> d;
for(i = 1; i <= m; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
addEdge(a, b, c, d);
}
bellman();
cout << flow();
return 0;
}