Pagini recente » Cod sursa (job #2733437) | Cod sursa (job #2637693) | Cod sursa (job #2224455) | Cod sursa (job #2527503) | Cod sursa (job #1514608)
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<bitset>
#define FOR(a,b,c) for(int a=b;a<=c;++a)
#define pb push_back
#define INF 100500000
// algoritmul cu Bellman-Ford optimizat
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int N,M,S,D;
int cap[360][360],cost[360][360],flux[360][360],dad[360],dist[360];
// cap[i][j]=capacitatea muchiei (i,j);
// flux[i][j]=fluxul muchiei (i,j) la un moment dat;
// cost[i][j]=costul muchiei (i,j);
// dist[i]=costul total de la sursa la nodul i la un moment dat
// dad[i]=nodul precedent nodului i la un moment dat
vector<int> v[360];
queue<int> Q;
bitset<360> in_queue;
// v=liste de adiacenta
// Q=coada folosita la algoritmul Bellman-Ford
// in_queue[i]=1 daca nodul i se afla in coada la acel moment
int Bellman_ford();
int main() {
f>>N>>M>>S>>D;
FOR (i,1,M) {
int x,y,c,z;
f>>x>>y>>c>>z;
v[x].pb(y);
v[y].pb(x);
cap[x][y]=c;
cost[x][y]=z;
cost[y][x]=-z;
}
int rez=0,costdist;
do { // cat timp gasesc un drum de avansare, adaug costul acestuia la costul total
costdist=Bellman_ford();
rez+=costdist;
}
while (costdist);
g<<rez;
f.close();g.close();
return 0;
}
int Bellman_ford() { // caut un drum de avansare de cost minim
FOR (i,1,N) {
dist[i]=INF;
dad[i]=-1;
}
in_queue.reset();
dist[S]=0;
Q.push(S);
in_queue.set(S,1);
while (!Q.empty()) {
int nod=Q.front();
Q.pop();
vector<int>::iterator it;
for (it=v[nod].begin();it<v[nod].end();++it) {
if (cap[nod][*it]!=flux[nod][*it] && dist[nod]+cost[nod][*it]<dist[*it]) {
dist[*it]=dist[nod]+cost[nod][*it];
dad[*it]=nod;
if (!in_queue.test(*it)) {
in_queue.set(*it,1);
Q.push(*it);
}
}
}
in_queue.set(nod,0);
}
if (dist[D]<INF-12500000) {
int fluxc=INF;
for (int i=D;i!=S;i=dad[i]) {
fluxc=min(fluxc,cap[dad[i]][i]-flux[dad[i]][i]);
}
for (int i=D;i!=S;i=dad[i]) {
flux[dad[i]][i]+=fluxc;
flux[i][dad[i]]-=fluxc;
}
return fluxc*dist[D];
}
return 0;
}