Pagini recente » Cod sursa (job #2173178) | Cod sursa (job #2325236) | Cod sursa (job #272301) | Cod sursa (job #410715) | Cod sursa (job #2984388)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
ifstream f ("fmcm.in");
ofstream g ("fmcm.out");
const int SIZE = 355;
const int INF = 0x3f3f3f3f;
struct Compare
{
inline bool operator() (pair <int, int> x, pair <int, int> y)
{
return x.second > y.second;
}
};
int n, m, s, t;
int parent[SIZE], dist[SIZE], cDist[SIZE], fDist[SIZE];
int capacity[SIZE][SIZE], cost[SIZE][SIZE];
vector <int> adj[SIZE];
void Read()
{
f >> n >> m >> s >> t;
for (int i = 1; i <= m; i++)
{
int x, y, flow, c;
f >> x >> y >> flow >> c;
adj[x].push_back(y);
adj[y].push_back(x);
capacity[x][y] += flow;
cost[x][y] += c;
cost[y][x] -= c;
}
}
void SPFA(int startNode)
{
memset(fDist, INF, sizeof(fDist));
vector <bool> inQueue(SIZE, false);
queue <int> q;
q.push(s);
inQueue[s] = true;
fDist[s] = 0;
while (q.empty() == false)
{
int node = q.front();
inQueue[node] = false;
q.pop();
for (unsigned int i = 0; i < adj[node].size(); i++)
{
int neighbour = adj[node][i];
if (capacity[node][neighbour] > 0 &&
cost[node][neighbour] + fDist[node] < fDist[neighbour])
{
fDist[neighbour] = fDist[node] + cost[node][neighbour];
if (inQueue[neighbour] == false)
{
q.push(neighbour);
inQueue[neighbour] = true;
}
}
}
}
}
void Dijkstra(int startNode)
{
memset(parent, -1, sizeof(parent));
memset(dist, INF, sizeof(dist));
memset(cDist, INF, sizeof(cDist));
priority_queue < pair <int, int>, vector < pair <int, int> >, Compare> pq;
dist[startNode] = 0, cDist[startNode] = 0;
pq.push(make_pair(startNode, dist[startNode]));
while (pq.empty() == false)
{
int node = pq.top().first;
int distanceToNode = pq.top().second;
pq.pop();
if (dist[node] < distanceToNode) continue;
for (unsigned int i = 0; i < adj[node].size(); i++)
{
int neighbour = adj[node][i];
if (capacity[node][neighbour] > 0 &&
cost[node][neighbour] + dist[node] + fDist[node] - fDist[neighbour] < dist[neighbour])
{
dist[neighbour] = cost[node][neighbour] + dist[node] + fDist[node] - fDist[neighbour];
cDist[neighbour] = cost[node][neighbour] + cDist[node];
parent[neighbour] = node;
pq.push(make_pair(neighbour, dist[neighbour]));
}
}
}
memcpy(fDist, cDist, sizeof(fDist));
}
int MinimumCostFlow(int s, int t)
{
int totalCost = 0;
SPFA(s);
while (true)
{
Dijkstra(s);
if (parent[t] == -1) break;
int newFlow = INF;
int node = t;
while (node != s)
{
int par = parent[node];
newFlow = min(newFlow, capacity[par][node]);
node = par;
}
node = t;
while (node != s)
{
int par = parent[node];
capacity[par][node] -= newFlow;
capacity[node][par] += newFlow;
node = par;
}
totalCost += (newFlow * fDist[t]);
}
return totalCost;
}
int main()
{
Read();
g << MinimumCostFlow(s, t);
return 0;
}