Pagini recente » Cod sursa (job #911652) | Cod sursa (job #141958) | Cod sursa (job #2821535) | Cod sursa (job #3216562) | Cod sursa (job #2582971)
#define NMAX 360
#define oo 0x3f3f3f3f
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int n, m, s, d;
int viz[NMAX], t[NMAX], Dmin[NMAX], Ddij[NMAX], Ddij_neg[NMAX];
int cap[NMAX][NMAX], flo[NMAX][NMAX], cost[NMAX][NMAX];
vector<int> graph[NMAX];
struct muc{
int my_node, d;
bool operator<(const muc &other) const{
if(d != other.d)
return d > other.d;
return my_node > other.my_node;
}
};
void read()
{
int x, y, c, p;
f>>n>>m>>s>>d;
for(int i = 1; i <= m; ++i)
{
f>>x>>y>>c>>p;
cap[x][y] = c;
cap[y][x] = 0;
cost[x][y] = p;
cost[y][x] = -p;
graph[x].push_back(y);
graph[y].push_back(x);
}
}
void bellman_ford()
{
queue<int> Q;
memset(Dmin, oo, sizeof(Dmin));
Q.push(s);
Dmin[s] = 0;
viz[s] = 1;
while(!Q.empty())
{
int from = Q.front();
Q.pop();
viz[from] = 0;
for(auto &v:graph[from])
if(cap[from][v] - flo[from][v] != 0 && Dmin[v] > Dmin[from] + cost[from][v])
{
Dmin[v] = Dmin[from] + cost[from][v];
if(viz[v] == 0)
{
Q.push(v);
viz[v] = 1;
}
}
}
}
bool dijkstra()
{
priority_queue<muc> Q;
memset(viz, 0, sizeof(viz));
memset(Ddij, oo, sizeof(Ddij));
memset(Ddij_neg, oo, sizeof(Ddij_neg));
Q.push({s, 0});
Ddij[s] = 0;
Ddij_neg[s] = 0;
while(!Q.empty())
{
muc from = Q.top();
Q.pop();
if(viz[from.my_node] == 1)
continue;
viz[from.my_node] = 1;
for(auto &v:graph[from.my_node])
if(cap[from.my_node][v] - flo[from.my_node][v] > 0)
{
int new_cost = cost[from.my_node][v] + Dmin[from.my_node] - Dmin[v];
if(Ddij[v] > Ddij[from.my_node] + new_cost)
{
t[v] = from.my_node;
Ddij[v] = Ddij[from.my_node] + new_cost;
Ddij_neg[v] = Ddij_neg[from.my_node] + cost[from.my_node][v];
Q.push({v, Ddij[v]});
}
}
}
memcpy(Dmin, Ddij_neg, sizeof(Ddij_neg));
return Ddij[d] != oo;
}
int main()
{
int dm = 0;
read();
bellman_ford(); // am costuri negative
while(dijkstra()) // 'cresc' costurile negative ca sa nu am pb cu dijkstra
{
for(auto &v:graph[n])
{
if(viz[v] == 0 || cap[v][n] - flo[v][n] == 0)
continue;
int act_flomax = oo;
for(int v = d; v != s; v = t[v])
act_flomax = min(act_flomax, cap[t[v]][v] - flo[t[v]][v]);
for(int v = d; v != s; v = t[v])
{
flo[t[v]][v] += act_flomax;
flo[v][t[v]] -= act_flomax;
}
dm += Dmin[d]*act_flomax;
}
}
g<<dm;
return 0;
}