Cod sursa(job #1130893)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 28 februarie 2014 16:17:40
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <list>

const int INF=0x03FFFFFF;
typedef std::pair<unsigned,int> PUI;
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);
    static std::vector<unsigned> tati(n+1,INF);
    static std::priority_queue<PUU,std::vector<PUU>,std::greater<PUU> > pq;

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

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

    while(!pq.empty()){
        int cdist=pq.top().first; unsigned cnod=pq.top().second;
        pq.pop();

        if(cdist==ndist[cnod])
            for(auto it=Adj[cnod].begin();it!=Adj[cnod].end();++it){
                int temp;
                if( (F[cnod][*it]>0) && (ndist[*it] > (temp=cdist+Dist[cnod]-Dist[*it]+Cst[cnod][*it])) ){
                    ndist[*it]=temp;
                    pq.push(PUU(temp,*it));
                    tati[*it]=cnod;
                    real_d[*it]=real_d[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*real_d[d];
        Dist.swap(real_d);
        return true;
    }
    else return false;

}

int main(){
    std::freopen("fmcm.in","rt",stdin);
    std::freopen("fmcm.out","wt",stdout);

    unsigned n,m,s,d;
    std::scanf("%d %d %d %d",&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; std::scanf("%d %d %d %d",&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));

    std::printf("%d \n",cstmin);
}