Pagini recente » Cod sursa (job #2196445) | Cod sursa (job #586484) | Cod sursa (job #1452667) | Cod sursa (job #1277395) | Cod sursa (job #2950387)
#include <bits/stdc++.h>
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
const int inf = 1e9;
int t;
int n, m;
int source, destination;
struct Edge
{
int u, v, cap, cost, flow;
};
vector<Edge> edges;
vector<vector<int>> poz;
vector<int> potential;
vector<int> dist2, dist;
vector<int> dad;
struct cmp
{
bool operator () (const int &u, const int &v)
{
return dist2[u] > dist2[v];
}
};
void addEdge(int u, int v, int cap, int cost, int flow = 0)
{
int m = edges.size();
edges.push_back({u, v, cap, cost, flow});
edges.push_back({v, u, 0, -cost, 0});
poz[u].push_back(m); //pozitia
poz[v].push_back(m + 1);
}
void bf()
{
queue<int> q;
vector<bool> inQ(n + 1); //in queue
dist = vector<int> (n + 1, inf);
dist[source] = 0;
q.push(source);
inQ[source] = 1;
while(!q.empty())
{
int u = q.front();
q.pop();
inQ[u] = 0;
for(const auto &it: poz[u])
{
int v = edges[it].v;
int cap = edges[it].cap;
int cost = edges[it].cost;
if(cap > 0 && dist[v] > dist[u] + cost)
{
dist[v] = dist[u] + cost;
if(!inQ[v])
{
q.push(v);
inQ[v] = 1;
}
}
}
}
}
bool dij()
{
priority_queue<int, vector<int>, cmp> pq;
vector<bool> inQ(n + 1);
dad = vector<int> (n + 1);
potential = dist;
dist = dist2 = vector<int> (n + 1, inf);
dist[source] = dist2[source] = 0;
pq.push(source);
inQ[source] = 1;
while(!pq.empty())
{
int u = pq.top();
pq.pop();
inQ[u] = 0;
for(const auto &it: poz[u])
{
int v = edges[it].v;
int cap = edges[it].cap;
int cost = edges[it].cost;
int flow = edges[it].flow;
if(cap - flow > 0 && dist2[v] + potential[v] > dist2[u] + potential[u] + cost)
{
dist2[v] = dist2[u] + potential[u] + cost - potential[v];
dist[v] = dist[u] + cost;
dad[v] = it;
if(!inQ[v])
{
pq.push(v);
inQ[v] = 1;
}
}
}
}
return dist2[destination] != inf;
}
int main()
{
f >> n >> m >> source >> destination;
edges = vector<Edge> (0);
poz = vector<vector<int>> (n + 1);
for(int i = 1; i <= m; i++)
{
int u, v, c, z;
f >> u >> v >> c >> z;
addEdge(u, v, c, z);
}
bf();
int maxFlow = 0, minCost = 0;
while(dij())
{
int flow = inf, cost = 0;
for(int u = destination; u != source; u = edges[dad[u]].u) //merg in sens invers de la destinatie la sursa
{
flow = min(flow, edges[dad[u]].cap - edges[dad[u]].flow); //actualizez fluxul
cost += edges[dad[u]].cost;
}
maxFlow += flow; //adun la raspuns
minCost += cost * flow;
for(int u = destination; u != source; u = edges[dad[u]].u)
{
edges[dad[u]].flow += flow;
edges[dad[u] ^ 1].flow -= flow;
}
}
g << minCost << '\n';
///Complexitate: O(n*m*m*log(n))
return 0;
}