Pagini recente » Istoria paginii utilizator/santa-claus | Cod sursa (job #498966) | Cod sursa (job #2675843) | Clasament simulare-5-1 | Cod sursa (job #2582968)
#include <fstream>
#include <cstring>
#include <bitset>
#include <vector>
#include <queue>
#include <set>
#define NMAX 360
#define oo 0x3f3f3f3f
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int n, m, s, d; // n noduri, m muchii, s sursa, d destinatia
int x, y, c, z; // arc de la x la y de capacitate c, cost z
int cap[NMAX][NMAX], flow[NMAX][NMAX], cost[NMAX][NMAX];
int dmin[NMAX]; // dist[i] = distanta de la sursa la i -> bellman ford
int dmindij[NMAX]; // distdij[i] = distanta de la sursa la i -> dijkstra !!niciun nr negativ
int tati[NMAX]; // pt a recrea drumul de cost minim
int dnealterat[NMAX]; // drum fara a lua in calcul artificiul pt pozitiv
struct muchie{
int y, cost;
bool operator<(const muchie &other) const{
if(cost == other.cost)
return y<other.y;
return cost<other.cost;
}
};
vector<muchie> graph[NMAX];
queue<int> Q;
void citire(){
f>>n>>m>>s>>d;
for(int i=1; i<=m; i++){
f>>x>>y>>c>>z;
graph[x].push_back({y, z});
graph[y].push_back({x, -z}); // graf rezidual
cap[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
}
}
void bellman_ford(){
bitset<NMAX>viz;
viz.reset();
memset(dmin, oo, sizeof(dmin));
dmin[s] = 0;
Q.push(s);
viz[s] = true;
while(!Q.empty()){
int nod = Q.front();
Q.pop();
for(auto v:graph[nod])
if(cap[nod][v.y]!=flow[nod][v.y] && dmin[nod] + v.cost < dmin[v.y]){ // daca poate trece "flow"
dmin[v.y] = dmin[nod] + v.cost;
if(!viz[v.y])
Q.push(v.y);
viz[v.y] = true;
}
viz[nod] = false;
}
}
int cost_nou(int cost, int nod1, int nod2){
return cost+dmin[nod1]-dmin[nod2];
}
bool dijkstra(){
set<muchie> S;
memset(dmindij, oo, sizeof(dmindij));
dmin[s] = 0;
dnealterat[s] = 0;
dmindij[s] = 0;
S.insert({s, 0}); // y = s, cu costul 0
while(!S.empty()){
int nod = S.begin()->y;
S.erase(S.begin());
for(auto v:graph[nod])
if(dmindij[nod] + cost_nou(v.cost, nod, v.y) < dmindij[v.y] && cap[nod][v.y]!=flow[nod][v.y]){
if(dmindij[v.y]!=oo)
S.erase({v.y, dmindij[v.y]});
dmindij[v.y] = dmindij[nod] + cost_nou(v.cost, nod, v.y);;
dnealterat[v.y] = dnealterat[nod] + v.cost;
tati[v.y] = nod;
S.insert({v.y, dmindij[v.y]});
}
}
return dmindij[d]!=oo; // daca am ajuns la n
}
void solve(){
int ans=0;
while(dijkstra()){
int maxFlow=oo;
for(int i = d; i!=s; i=tati[i])
maxFlow=min(maxFlow, cap[tati[i]][i] - flow[tati[i]][i]);
if(maxFlow == 0)
continue;
ans += maxFlow*dnealterat[d];
for(int i=d; i!=s; i=tati[i]){
flow[tati[i]][i]+=maxFlow;
flow[i][tati[i]]-=maxFlow;
}
for(int i=1; i<=n; i++)
dmin[i] = dnealterat[i];
}
g<<ans<<" ";
}
int main()
{
citire();
bellman_ford();
solve();
return 0;
}