Cod sursa(job #1123103)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 25 februarie 2014 22:38:54
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <fstream>
#include <vector>
#include <queue>
#include <list>

const int INF=0x03FFFFFF;
typedef std::pair<unsigned,unsigned> PUU;

inline void BellmanFord(std::vector<int> &Dist, const unsigned n, const unsigned s,
						const std::vector< std::list< unsigned > > &Adj,
						const std::vector< std::vector<int> > &Cst,
						const std::vector< std::vector<unsigned> > &F){
	std::vector<bool> enqueued(n+1,false);
	std::queue<unsigned> q;
	q.push(s);
	while(!q.empty()){
		unsigned f=q.front(); q.pop(); enqueued[f]=false;
		for(auto it=Adj[f].begin();it!=Adj[f].end();++it)
			if(Dist[*it]>Dist[f]+Cst[f][*it]&&F[f][*it]!=0){
				Dist[*it]=Dist[f]+Cst[f][*it];
				if(!enqueued[*it]) q.push(*it);
			}
	}
}

bool ameliorare_Dijkstra(int &cstmin, const unsigned &n, const unsigned &s, const unsigned &d,
						const std::vector< std::list< unsigned > > &Adj,
						const std::vector< std::vector<int> > &Cst,
						std::vector< std::vector<unsigned> > &F,
						std::vector<int> &Dist){
	std::vector<int> ndist(n+1,INF);
	std::vector<unsigned> tati(n+1,INF);
	//std::vector<bool> visited(n+1,false);
	std::priority_queue<PUU> pq;

	std::vector<int> newDist(n+1,INF);


	pq.push(PUU(0,s)); ndist[s]=0;
	newDist[s]=0;

	while(!pq.empty()){
		int cdist=pq.top().first; unsigned cnod=pq.top().second;
		pq.pop(); //visited[cnod]=true;

		if(cdist==ndist[cnod])
			for(auto it=Adj[cnod].begin();it!=Adj[cnod].end();++it)
				if((F[cnod][*it]>0) && (ndist[*it] > cdist+Dist[cnod]-Dist[*it]+Cst[cnod][*it]) ){
					ndist[*it]=cdist+Dist[cnod]-Dist[*it]+Cst[cnod][*it];
					pq.push(PUU(ndist[*it],*it));
					tati[*it]=cnod;
					newDist[*it]=newDist[cnod]+Cst[cnod][*it];
				}
	}

	if(ndist[d]!=INF){ //am gasit drum de ameliorare
		unsigned cflux=INF;
		for(unsigned i=d;i!=s;i=tati[i]) if(F[tati[i]][i]<cflux) cflux=F[tati[i]][i];

		for(unsigned i=d;i!=s;i=tati[i]){
			F[tati[i]][i]-=cflux;
			F[i][tati[i]]+=cflux;
		}
		cstmin+=cflux*newDist[d];

		Dist.swap(newDist);
		return true;
	}
	else return false;

}

int main(){
    std::ifstream fin("fmcm.in");
    std::ofstream fout("fmcm.out");

    unsigned n,m,s,d;
    fin>>n>>m>>s>>d;

    std::vector< std::list< unsigned > > Adj(n+1);
    std::vector< std::vector<unsigned> > F(n+1,std::vector<unsigned>(n+1,0));
    std::vector< std::vector<int> > Cst(n+1,std::vector<int>(n+1,INF));

    for(unsigned i=0;i<m;++i){
		unsigned x,y,c; int z; fin>>x>>y>>c>>z;
		Adj[x].push_back(y);
		Adj[y].push_back(x);
		F[x][y]=c;
		Cst[x][y]=z;
		Cst[y][x]=-z;
    }

	std::vector<int> Dist(n+1,INF);
	Dist[s]=0;

	BellmanFord(Dist,n,s,Adj,Cst,F);

	int cstmin=0;

	while(ameliorare_Dijkstra(cstmin,n,s,d,Adj,Cst,F,Dist));

	fout<<cstmin<<'\n';

}