Pagini recente » Cod sursa (job #1572145) | Istoria paginii runda/ioi_2020/clasament | Cod sursa (job #1461749) | Cod sursa (job #2936945) | Cod sursa (job #1967056)
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 360;
const int inf = (1 << 27);
int n, m, s, d;
int flux[N][N];
int capacitate[N][N];
int cost[N][N];
int oldDist[N];
int dist[N];
int realDist[N];
vector<int> vecini[N];
int sol = 0;
int solx = 0;
int tata[N];
priority_queue<pair<int, int> > Q;
int inq[N];
void citire()
{
scanf("%d %d %d %d", &n, &m, &s, &d);
s--;
d--;
int tmp1, tmp2, tmp3, tmp4;
for(int i = 0; i < m; i++)
{
scanf("%d %d %d %d", &tmp1, &tmp2, &tmp3, &tmp4);
tmp1--;
tmp2--;
vecini[tmp1].push_back(tmp2);
vecini[tmp2].push_back(tmp1);
capacitate[tmp1][tmp2] = tmp3;
cost[tmp1][tmp2] = tmp4;
cost[tmp2][tmp1] = -tmp4;
}
}
void bellmanFord()
{
for(int i = 0; i < n; i++)
{
oldDist[i] = inf;
}
queue<int> Q;
Q.push(s);
oldDist[s] = 0;
inq[s] = true;
while(Q.empty() == false)
{
int x = Q.front();
inq[x] = false;
Q.pop();
int l = vecini[x].size();
for(int i = 0; i < l; i++)
{
if(flux[x][vecini[x][i]] < capacitate[x][vecini[x][i]])
{
if(oldDist[vecini[x][i]] <= oldDist[x] + cost[x][vecini[x][i]])
{
continue;
}
oldDist[vecini[x][i]] = oldDist[x] + cost[x][vecini[x][i]];
if(inq[vecini[x][i]] == true)
{
continue;
}
inq[vecini[x][i]] = true;
Q.push(vecini[x][i]);
}
}
}
}
bool dijkstra()
{
for(int i = 0; i < n; i++)
{
dist[i] = inf;
}
Q.push(make_pair(0, s));
tata[s] = s;
dist[s] = 0;
realDist[s] = 0;
while(Q.empty() == false)
{
int x = Q.top().second;
int y = Q.top().first;
Q.pop();
if(dist[x] != y)
{
continue;
}
int l = vecini[x].size();
for(int i = 0; i < l; i++)
{
if(flux[x][vecini[x][i]] < capacitate[x][vecini[x][i]])
{
int z = dist[x] + cost[x][vecini[x][i]] + oldDist[x] - oldDist[vecini[x][i]];
if(dist[vecini[x][i]] > z)
{
dist[vecini[x][i]] = z;
realDist[vecini[x][i]] = realDist[x] + cost[x][vecini[x][i]];
tata[vecini[x][i]] = x;
Q.push(make_pair(dist[vecini[x][i]], vecini[x][i]));
}
}
}
}
if(dist[d] != inf)
{
return true;
}
return false;
}
void solve()
{
while(dijkstra() == true)
{
int valMin = inf;
for(int x = d; x != s; x = tata[x])
{
valMin = min(valMin, capacitate[tata[x]][x] - flux[tata[x]][x]);
}
solx += realDist[d] * valMin;
sol += valMin;
for(int x = d; x != s; x = tata[x])
{
flux[tata[x]][x] += valMin;
flux[x][tata[x]] -= valMin;
}
for(int i = 0; i < n; i++)
{
oldDist[i] = realDist[i];
}
}
}
void afisare()
{
printf("%d", solx);
}
int main()
{
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
citire();
bellmanFord();
solve();
afisare();
return 0;
}