Pagini recente » Cod sursa (job #581456) | Cod sursa (job #499798) | Cod sursa (job #898456) | Cod sursa (job #1941352) | Cod sursa (job #2585881)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#include <set>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
typedef long long lint;
const int INF = 0x3f3f3f3f;
struct nod{
int a, v = INF;
bool operator<(const nod &rhs)const{
if(v != rhs.v){
return v < rhs.v;
}else{
return a < rhs.a;
}
}
};
int n, m, s, d;
int cap[410][410], flo[410][410];
int rcst[410][410];
vector<int> gra[410];
void read(){
fin >> n >> m >> s >> d;
for(int i = 0; i < m; ++i){
int a, b;
fin >> a >> b;
fin >> cap[a][b] >> rcst[a][b];
rcst[b][a] = -rcst[a][b];
gra[a].push_back(b);
gra[b].push_back(a);
}
}
bool bfs(){
static queue<int> qu;
static bitset<410> vi;
vi.reset();
qu.push(s);
vi[s] = true;
while(!qu.empty()){
int a = qu.front();
qu.pop();
for(auto b : gra[a]){
if(!vi[b] && flo[a][b] < cap[a][b]){
vi[b] = true;
if(b != d)qu.push(b);
}
}
}
return vi[d];
}
int dist[410];
int rdist[410];
void nuke(){
for(int i = 1; i <= n; ++i){
dist[i] = INF;
}
dist[s] = 0;
}
void bellman(){
static queue<int> qu;
static bitset<410> vi;
nuke();
qu.push(s);
vi[s] = true;
while(!qu.empty()){
int a = qu.front();
qu.pop();
vi[a] = false;
for(auto b : gra[a]){
int v = dist[a]+rcst[a][b];
if(v < dist[b] && cap[a][b] != 0){
dist[b] = v;
if(!vi[b]){
qu.push(b);
vi[b] = true;
}
}
}
}
}
int cst[410][410];
void postbellman(){
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= n; ++j){
cst[i][j] = dist[i] - dist[j] + rcst[i][j];
}
}
}
set<nod> pq;
int dad[410];
void dijkstra(){
nuke();
pq.insert({s, 0});
rdist[s] = 0;
while(!pq.empty()){
int a = pq.begin()->a;
pq.erase(pq.begin());
for(auto b : gra[a]){
int v = dist[a] + cst[a][b];
if(v < dist[b] && flo[a][b] < cap[a][b]){
dad[b] = a;
if(dist[b] != INF){
pq.erase({b, dist[b]});
}
dist[b] = v;
rdist[b] = rdist[a]+rcst[a][b];
pq.insert({b, dist[b]});
}
}
}
}
lint updateflow(){
int fmin = INF;
for(int x = d; x != s; x = dad[x]){
fmin = min(fmin, cap[dad[x]][x] - flo[dad[x]][x]);
}
if(fmin != 0){
for(int x = d; x != s; x = dad[x]){
flo[dad[x]][x] += fmin;
flo[x][dad[x]] -= fmin;
}
return fmin*rdist[d];
}
return 0;
}
lint ans = 0;
void maxflow(){
while(bfs()){
dijkstra();
ans += updateflow();
}
}
void solve(){
bellman();
postbellman();
maxflow();
}
int main(){
read();
solve();
fout << ans;
return 0;
}