Pagini recente » Cod sursa (job #1622010) | Cod sursa (job #1282848) | Clasament remember-mihai-patrascu | Cod sursa (job #49554) | Cod sursa (job #703776)
Cod sursa(job #703776)
#include<cstdio>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#define infile "fmcm.in"
#define outfile "fmcm.out"
#define n_max 355
#define INF 1<<30
#define nxt *it
#define pii pair<int, int>
#define mkp make_pair
#define pb push_back
#define mkp make_pair
#define FOR(g) \
for(vector<int> ::iterator it = g.begin(); it!=g.end(); ++it)
using namespace std;
vector <int> v[n_max];
int H[n_max], Poz[n_max];
int NH;
int Cost[n_max][n_max], C[n_max][n_max], F[n_max][n_max];
int Dist[n_max], T[n_max];
int Src, Sink, Sum;
int N, M;
long long MaxFlow;
void citeste()
{
freopen(infile,"r",stdin);
scanf("%d %d %d %d", &N, &M, &Src, &Sink);
int x, y, cap, cost;
while(M--)
{
scanf("%d %d %d %d", &x, &y, &cap, &cost);
v[x].pb(y);
v[y].pb(x);
C[x][y] = cap;
Cost[x][y] = cost;
Cost[y][x] = -cost;
}
fclose(stdin);
}
void BellmanFord()
{
queue < int > q;
bitset < n_max > uz;
for(int i=1; i<=N; ++i)
Dist[i] = INF;
q.push(Src);
Dist[Src] = 0;
while(!q.empty())
{
int x = q.front();
q.pop();
FOR(v[x])
if(C[x][nxt] > F[x][nxt] && Dist[x] + Cost[x][nxt] < Dist[nxt]){
Dist[nxt] = Dist[x] + Cost[x][nxt];
if(uz[nxt])
continue;
q.push(nxt);
uz[nxt] = 1;
}
uz[x] = 0;
}
Sum = Dist[Sink];
}
inline void pop()
{
H[1] = H[NH--];
Poz[H[1]] = 1;
int ls, rs, son, k = 1;
while(true)
{
son = k;
ls = 2 * k;
rs = 2 * k + 1;
if(ls <= NH && Dist[H[ls]] < Dist[H[son]])
son = ls;
if(rs <= NH && Dist[H[rs]] < Dist[H[son]])
son = rs;
if(son == k)
return;
swap(Poz[H[k]], Poz[H[son]]);
swap(H[k], H[son]);
k = son;
}
}
inline void push(int x)
{
if(!Poz[x]){
H[++NH] = x;
Poz[x] = NH;
}
int k = Poz[x];
while(k>1 && Dist[H[k]] < Dist[H[k/2]])
{
swap(Poz[H[k]], Poz[H[k/2]]);
swap(H[k], H[k/2]);
k = k/2;
}
}
int Dijkstra()
{
for(int x=1; x<=N; ++x)
FOR(v[x])
if(Dist[x] != INF && Dist[nxt] != INF)
Cost[x][nxt] += Dist[x] - Dist[nxt];
for(int i=1; i<=N; ++i){
Dist[i] = INF;
T[i] = Poz[i] = 0;
}
Dist[Src] = 0;
T[Src] = -1;
NH = 0;
push(Src);
while(NH)
{
int x = H[1];
pop();
FOR(v[x])
if(C[x][nxt] > F[x][nxt] && Dist[x] + Cost[x][nxt] < Dist[nxt])
{
Dist[nxt] = Dist[x] + Cost[x][nxt];
T[nxt] = x;
push(nxt);
}
}
return T[Sink] != 0;
}
void rezolva()
{
BellmanFord();
while(Dijkstra())
{
int flow = INF;
for(int i = Sink; i != Src; i = T[i])
flow = min(flow, C[T[i]][i] - F[T[i]][i]);
for(int i = Sink; i != Src; i = T[i]){
F[T[i]][i] += flow;
F[i][T[i]] -= flow;
}
Sum += Dist[Sink];
MaxFlow += flow * Sum;
}
}
void afiseaza()
{
freopen(outfile,"w",stdout);
printf("%lld\n", MaxFlow);
fclose(stdout);
}
int main()
{
citeste();
rezolva();
afiseaza();
return 0;
}