Pagini recente » Cod sursa (job #2917967) | Profil CaldareaCiprian | Cod sursa (job #646945) | Clasament 3 | Cod sursa (job #3226952)
#include<bits/stdc++.h>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define int long long
const int INF = 1e18;
int n,m;
struct edge
{
int from,to;
int cap;
int cost;
};
vector<edge> edges;
vector<int> con[355];
int pi[355];
int prec[355];
int dist[355];
void add_edge(int from, int to, int cap, int cost)
{
con[from].push_back(edges.size()); edges.push_back({from,to,cap,cost});
con[to].push_back(edges.size()); edges.push_back({to,from,0,-cost});
}
bool get_path(int src, int dest)
{
for(int i=1;i<=n;i++)
dist[i]=INF;
dist[src]=0;
priority_queue<pair<int,int>> pq;
pq.push({0,src});
while(!pq.empty())
{
int nod = pq.top().second;
int cdist = -pq.top().first;
pq.pop();
if(dist[nod]!=cdist)
continue;
for(auto e_id:con[nod])
{
edge e = edges[e_id];
int val = dist[nod] + pi[nod] - pi[e.to] + e.cost;
if(e.cap>0 && dist[e.to] > val)
{
dist[e.to] = val;
prec[e.to] = e_id;
pq.push({-dist[e.to],e.to});
}
}
}
if(dist[dest]<INF)
return 1;
return 0;
}
pair<int,int> maxflow_mincost(int src, int dest)
{
int flow=0,cost=0;
for(int i=1;i<=n;i++)
pi[i]=INF;
pi[src]=0;
for(int pas=1;pas<=n;pas++)
for(auto e:edges)
if(e.cap>0)
pi[e.to] = min(pi[e.to], pi[e.from]+e.cost);
while(get_path(src,dest))
{
for(int i=1;i<=n;i++)
pi[i] += dist[i];
int mnm=INF,cur=dest,sumcost=0;
while(cur!=src)
{
mnm = min(mnm, edges[prec[cur]].cap);
sumcost += edges[prec[cur]].cost;
cur = edges[prec[cur]].from;
}
flow += mnm;
cost += sumcost*mnm;
cur=dest;
while(cur!=src)
{
edges[prec[cur]].cap -= mnm;
edges[prec[cur]^1].cap += mnm;
cur = edges[prec[cur]].from;
}
}
return {flow,cost};
}
signed main()
{
int src,dest;
fin>>n>>m>>src>>dest;
int x,y,c,z;
for(int i=0;i<m;i++)
{
fin>>x>>y>>c>>z;
add_edge(x,y,c,z);
}
pair<int,int> rez = maxflow_mincost(src,dest);
fout<<rez.second;
return 0;
}