Pagini recente » Cod sursa (job #2069224) | Cod sursa (job #1608542) | Cod sursa (job #421794) | Cod sursa (job #1556512) | Cod sursa (job #1659693)
// Minimum Cost Maximum Flow.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define NMax 600
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
struct Pair {
int n, c, ant;
Pair(int _n, int _c, int _ant)
{
n = _n;
c = _c;
ant = _ant;
}
Pair() {}
};
vector<short int> v[NMax];
int n, m, s, d, i, a, b, c, z, S, MaxFlux = 1000000000;
int dist[NMax];
int maxx[NMax][NMax], cons[NMax][NMax], cost[NMax][NMax], _cost;
short int realCost[NMax][NMax];
Pair way[NMax];
void _read()
{
fin >> n >> m >> s >> d;
for (i = 1; i <= m; i++)
{
fin >> a >> b >> c >> z;
v[a].push_back(b);
v[b].push_back(a);
maxx[a][b] = c;
cost[a][b] = realCost[a][b] = z ;
cost[b][a] = realCost[b][a] = -z ;
}
}
inline bool CanGoTo(int n1, int n2)
{
return !(cons[n1][n2] == maxx[n1][n2] || way[n2].n != 0);
}
inline bool comp(Pair a, Pair b)
{
return a.c > b.c;
}
vector<Pair> que;
Pair tmp, tmp2;
inline void dijkstra()
{
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < v[i].size(); j++)
{
cost[i][v[i][j]] += dist[i] - dist[v[i][j]];
}
}
memset(dist, 0x3f, sizeof(dist));
dist[s] = 0;
que.push_back( *(new Pair(s,0,s)) );
int nr = 0;
while (que.size())
{
nr++;
tmp = que.front();
pop_heap(que.begin(),que.end(),comp);
que.pop_back();
if (way[tmp.n].n == 0)
{
way[tmp.n] = tmp;
for (int i = 0; i < v[tmp.n].size(); i++)
{
if (CanGoTo(tmp.n, v[tmp.n][i]))
{
if (dist[v[tmp.n][i]] > dist[tmp.n] + cost[tmp.n][v[tmp.n][i]])
{
dist[v[tmp.n][i]] = dist[tmp.n] + cost[tmp.n][v[tmp.n][i]];
tmp2.n = v[tmp.n][i];
tmp2.c = tmp.c + cost[tmp.n][tmp2.n];
tmp2.ant = tmp.n;
que.push_back(tmp2);
push_heap(que.begin(), que.end(), comp);
}
}
}
}
}
return;
}
int dfs(int n)
{
int a = MaxFlux;
while (n != way[n].ant)
{
a = min(a, maxx[way[n].ant][n] - cons[way[n].ant][n]);
n = way[n].ant;
}
return a;
}
void saturate(int x, int n)
{
while (n != way[n].ant)
{
cons[way[n].ant][n] += x;
cons[n][way[n].ant] -= x;
n = way[n].ant;
}
}
bool find()
{
memset(way, 0, sizeof(way));
dijkstra();
que.clear();
if (!way[d].n)
return false;
int a = dfs(d);
_cost += dist[d];
S += _cost * a;
saturate(a,d);
return true;
}
void BellmanFord()
{
memset(dist, 0x3f, sizeof(dist));
bool ok = 1;
dist[s] = 0;
for (int j = 1; j <= n && ok; j++) {
ok = 0;
for (int nod = 1; nod <= n; nod++)
for (i = 0; i<v[nod].size(); i++)
if (maxx[nod][v[nod][i]]>0 && dist[nod] + cost[nod][v[nod][i]]<dist[v[nod][i]]) {
dist[v[nod][i]] = dist[nod] + cost[nod][v[nod][i]];
ok = 1;
}
}
_cost = dist[d];
}
void think()
{
BellmanFord();
while (find());
}
int main()
{
_read();
think();
fout << S;
return 0;
}