Pagini recente » Cod sursa (job #1927519) | Cod sursa (job #2687132) | Cod sursa (job #2515678) | Cod sursa (job #1156113) | Cod sursa (job #1535078)
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAXN=350,INF=2000000000;
//FILE* f = stdin;
//FILE* h = stdout;
FILE* f = fopen("fmcm.in","r");
FILE* h = fopen("fmcm.out","w");
int N, M;
vector<int> graf[1 + MAXN];
int S, D;
int capacitate[1 + MAXN][1 + MAXN];
int cost[1 + MAXN][1 + MAXN];
int flux[1 + MAXN][1 + MAXN];
struct Nod {
int index;
int cost;
const bool operator < (const Nod &b) const {
return this->cost > b.cost;
}
};
queue<Nod> q;
priority_queue<Nod> pq;
int fost[1 + MAXN];
int distantaJ[1 + MAXN];
int distantaN[1 + MAXN];
int distanta[1 + MAXN];
int fluxtotal,costtotal;
bool dijkstra(){
memset(fost,0,sizeof(fost));
memset(distantaN,0,sizeof(distantaN));
memset(distanta,0x3f,sizeof(distanta));
pq.push(Nod({S, 0}));
distanta[S] = 0;
fost[S]=S;
while ( pq.size()>0 ){
int nod = pq.top().index;
int costcurent = pq.top().cost;
pq.pop();
if (distanta[nod] == costcurent) {
for ( int i = 0; i < (int)graf[nod].size(); ++i ){
int vecin = graf[nod][i];
if (capacitate[nod][vecin]-flux[nod][vecin] > 0){
if (costcurent+cost[nod][vecin]+distantaJ[nod]-distantaJ[vecin] < distanta[vecin]) {
pq.push(Nod{vecin,costcurent+cost[nod][vecin]+distantaJ[nod]-distantaJ[vecin]});
fost[vecin]=nod;
distantaN[vecin] = distantaN[nod]+cost[nod][vecin];
distanta[vecin] = costcurent+cost[nod][vecin]+distantaJ[nod]-distantaJ[vecin];
}
}
}
}
}
memcpy(distantaJ, distantaN, sizeof(distantaJ));
return fost[D] > 0;
}
void johnson(){
memset(distantaJ,0x3f,sizeof(distantaJ));
distantaJ[S] = 0;
q.push({S, 0});
while (!q.empty()) {
int nod = q.front().index;
int costNod = q.front().cost;
q.pop();
if (costNod == distantaJ[nod]) {
//printf("%d %d\n", nod, costNod);
for (int i = 0; i < (int)graf[nod].size(); ++i) {
int vecin = graf[nod][i];
if (costNod + cost[nod][vecin] < distantaJ[vecin]) {
distantaJ[vecin] = costNod + cost[nod][vecin];
q.push({vecin, distantaJ[vecin]});
}
}
}
}
}
int main(void) {
int i;
fscanf(f,"%d%d%d%d", &N, &M, &S, &D);
for (i = 0; i < M; ++i) {
int x, y, fl, co;
fscanf(f,"%d%d%d%d", &x, &y, &fl, &co);
graf[x].push_back(y);
//graf[y].push_back(x);
capacitate[x][y] = fl;
capacitate[y][x] = 0;
cost[x][y]=co;
cost[y][x]=-co;
}
johnson();
//*
for (int i = 1; i <= N; ++i) {
for (int j = 0; j < (int)graf[i].size(); ++j) {
int vecin = graf[i][j];
if (capacitate[vecin][i] == 0) {
graf[vecin].push_back(i);
}
}
}//*/
/*
for (int i = 1; i <= N; ++i) {
for (int j = 0; j < (int)graf[i].size(); ++j) {
int vecin = graf[i][j];
printf("%d %d -> %d\n", i, vecin, costNou[i][vecin]);
}
}//*/
while ( dijkstra() ){
int nod=D;
int mincapacitate = INF;
while (nod != fost[nod]){
if (capacitate[fost[nod]][nod]-flux[fost[nod]][nod] < mincapacitate)
mincapacitate = capacitate[fost[nod]][nod]-flux[fost[nod]][nod];
nod = fost[nod];
}
nod=D;
while (nod != fost[nod]){
flux[fost[nod]][nod] += mincapacitate;
flux[nod][fost[nod]] -= mincapacitate;
nod=fost[nod];
}
}
for ( int i=1;i<=N;++i ){
fluxtotal+=flux[S][i];
}
for ( int i=1;i<=N;++i )
for ( int j=1;j<=N;++j )
if ( flux[i][j]>0 )
costtotal+=flux[i][j]*cost[i][j];
//fprintf(h,"%d\n", fluxtotal);
fprintf(h,"%d\n", costtotal);
return 0;
}