Pagini recente » Cod sursa (job #770007) | Cod sursa (job #1489217) | Monitorul de evaluare | Cod sursa (job #359302) | Cod sursa (job #993346)
Cod sursa(job #993346)
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define maxn 352
#define inf 350001
#define vint vector<int>::iterator
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
//general
vector <int> G[maxn];
int C[maxn][maxn],Cost[maxn][maxn],F[maxn][maxn];
int n,m,s,d,a,b,c,z,flowcost,flow;
//for Bellman-Ford
queue <int> Q;
int D[maxn]; bool viz[maxn];
//for Dijkstra
int h[maxn],hpoz[maxn];
int path[maxn],old_d[maxn],real_d[maxn];
int hsize;
inline int father (const int &x)
{
return x>>1;
}
inline int left_son (const int &x)
{
return x<<1;
}
inline int right_son (const int &x)
{
return (x<<1)+1;
}
void upheap (int poz)
{
int pullout = h[poz];
while (D[pullout] < D[h[father(poz)]])
{
h[poz] = h[father(poz)];
hpoz[h[poz]] = poz;
poz >>= 1;
}
h[poz] = pullout;
hpoz[h[poz]] = poz;
}
void downheap (int poz)
{
int pullout = h[poz], ok = 0;
while (ok!=-1)
{
ok=-1;
if (left_son(poz) <= hsize && D[pullout] > D[h[left_son(poz)]]) ok=0;
if (right_son(poz) <= hsize && D[pullout] > D[h[right_son(poz)]])
{
if (ok==0) {if (D[h[right_son(poz)]] < D[h[left_son(poz)]]) ok=1;}
else ok=1;
}
if (ok!=-1)
{
h[poz] = h[(poz<<1)+ok];
hpoz[h[poz]] = poz;
poz = (poz<<1) + ok;
}
}
h[poz] = pullout;
hpoz[h[poz]] = poz;
}
bool dijkstra ()
{
for (int i=1; i<=n+1; ++i) D[i]=inf, viz[i]=0, h[i]=i, hpoz[i]=i;
D[s] = 0;
swap (h[s],h[1]);
swap (hpoz[s],hpoz[1]);
hsize = n;
while (D[h[1]]!=inf)
{
int x = h[1];
if (viz[x]) continue;
viz[x]=1;
for (vint it = G[x].begin(); it!=G[x].end(); ++it)
{
if (C[x][*it]==F[x][*it]) continue;
int cst = D[x] + Cost[x][*it] + old_d[x] - old_d[*it];
if (cst < D[*it])
{
D[*it] = cst;
real_d[*it] = real_d[x] + Cost[x][*it];
path[*it] = x;
upheap (hpoz[*it]);
}
}
h[1] = h[hsize];
hpoz[h[1]] = 1;
h[hsize] = n+1;
--hsize;
downheap (1);
}
return D[d]!=inf;
}
void bellman_ford ()
{
for (int i=1; i<=n; ++i) old_d[i]=inf;
old_d[s]=0;
Q.push(s);
viz[s]=1;
while (!Q.empty())
{
int x = Q.front();
for (vint it = G[x].begin(); it!=G[x].end(); ++it)
{
if (C[x][*it]==F[x][*it]) continue;
if (old_d[x] + Cost[x][*it] < old_d[*it])
{
old_d[*it] = old_d[x] + Cost[x][*it];
if (!viz[*it])
{
viz[*it]=1;
Q.push(*it);
}
}
}
viz[x] = 0;
Q.pop();
}
}
int main()
{
fin>>n>>m>>s>>d;
for (int i=1; i<=m; ++i)
{
fin>>a>>b>>c>>z;
C[a][b] = c;
Cost[a][b] = z;
Cost[b][a] = -z;
G[a].push_back(b);
G[b].push_back (a);
}
bellman_ford ();
flowcost=0,flow=0;
while (dijkstra())
{
int minf = inf;
for (int i = d; i!=s; i=path[i])
{
minf = min (minf,C[path[i]][i]-F[path[i]][i]);
}
flow += minf;
flowcost += minf * real_d[d];
for (int i = d; i!=s; i=path[i])
{
F[path[i]][i] += minf;
F[i][path[i]] -= minf;
}
memcpy (old_d, real_d, sizeof(real_d));
}
fout<<flowcost;
return 0;
}