Pagini recente » Cod sursa (job #2099150) | Cod sursa (job #1357914) | Cod sursa (job #1635856) | Cod sursa (job #2099178) | Cod sursa (job #3137019)
#include<bits/stdc++.h>
using namespace std;
const int M=25010;
const int N=351;
const int oo=2000000000;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int n,m,s,d,i,j,k,cp,cs,cap[N][N],flow[N][N],q[N],
dad[N],P[N],price[N][N],PRICE,djikstra();
vector<int> v[N];
deque<int> Q;
void upd(),bellman();
void printP()
{
for(int i=1;i<=n;i++,cout<<' ')
cout<<P[i];
cout<<'\n';
}
int main()
{
f>>n>>m>>s>>d;
for(; m; m--)
{
int x,y,cp,cs;
f>>x>>y>>cp>>cs;
cap[x][y]=cp;
price[x][y]=cs;
price[y][x]=-cs;
v[x].push_back(y);
v[y].push_back(x);
}
bellman();
for(; djikstra();)upd();
g<<PRICE;
return 0;
}
void bellman()
{
queue<int> Q;
for(int i=1; i<=n; i++)
P[i]=oo;
P[s]=0;
dad[s]=s;
Q.push(s);
q[s]=1;
for(; Q.size();)
{
int nod=Q.front();
Q.pop();
q[nod]=0;
for(auto vec:v[nod])
if(cap[nod][vec]-flow[nod][vec]>0&&P[vec]>P[nod]+price[vec][nod])
{
if(!q[vec])
{
q[vec]=1;
Q.push(vec);
}
dad[vec]=nod;
P[vec]=P[nod]+price[nod][vec];
}
}
cs=P[d];
}
int djikstra()
{
/// refac costurile pe reteaua reziduala
for(int nod=1; nod<=n; nod++)
{
if(P[nod]==oo)continue;/// nu mai am drum spre nodul i
/// in reteaua reziduala
for(auto vec:v[nod])
{
if(P[vec]==oo)continue;/// nu mai am drum spre vecin in reteaua
/// reziduala
price[nod][vec]+=P[nod]-P[vec];
/// refac costul nod i -> vecin sa am cost pozitiv
}
}
/// djikstra cu noul graf
priority_queue<pair<int,int>> pq;
for(i=1; i<=n; i++)
{
P[i]=oo;
dad[i]=i;
}
/// reinitializez costurile cu oo
pq.push(make_pair(0,s));
P[s]=0;
/// pun in coada de prioritati djikstra sursa cu cost 0
/// aplic djikstra
///P[s]=0;H[s]=PH[s]=1;H[1]=PH[1]=s;
while(pq.size())
{
int nod,cost;
tie(cost,nod)=pq.top();
pq.pop();
cost=-cost;///in djikstra costurile se pun cu semn schimbat
for(auto vec:v[nod])
if(cap[nod][vec]>flow[nod][vec])
if(P[vec]>cost+price[nod][vec])
{
P[vec]=cost+price[nod][vec];
dad[vec]=nod;
pq.push(make_pair(-P[vec],vec));
}
}
if(P[d]==oo)/// nu am ajuns la destinatie
return 0;
return 1;/// am ajuns la destinatie
}
void upd()
{
cs+=P[d];
/// costul real la destinatie =
/// costul fals+costul la destinatie
int flowNow=oo,x=dad[d],y=d;
/// sursa este singurul nod pt care dad[x]=x
while(x!=y)
{
flowNow=min(flowNow,cap[x][y]-flow[x][y]);
x=dad[x];
y=dad[y];
}
x=dad[d];
y=d;
while(x!=y)
{
flow[x][y]+=flowNow;
flow[y][x]-=flowNow;
x=dad[x];
y=dad[y];
}
PRICE+=flowNow*cs;
}