Cod sursa(job #2250736)

Utilizator RaduMirceaAndreiRadu Mircea Andrei RaduMirceaAndrei Data 30 septembrie 2018 17:03:37
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
# include <fstream>
# include <vector>
# include <queue>
# define f first
# define s second
# define DIM 355
# define INF 1000000000
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
vector<int> Lista[DIM];
queue<int> q;
pair<int,int> h[DIM*DIM];
int c[DIM][DIM],f[DIM][DIM],val[DIM][DIM];
int Marcat[DIM],d[DIM],dis[DIM],aux[DIM],t[DIM];
int n,m,S,D,i,x,y,cap,cost,mn,sol,nh;
void add(int val,int poz){
    h[++nh].f=val;
    h[nh].s=poz;
    int c=nh,p=nh/2;
    while(p!=0){
        if(h[c].f<h[p].f){
            swap(h[c],h[p]);
            c=p;
            p/=2;
        }
        else
            break;
    }
}
void off(){
    h[1]=h[nh--];
    int c=2,p=1;
    while(c<=nh){
        if(h[c].f>h[c+1].f&&c<nh)
            c++;
        if(h[c].f<h[p].f){
            swap(h[c],h[p]);
            p=c;
            c*=2;
        }
        else
            break;
    }
}
bool flux(){
    for(int i=1;i<=n;i++){
        d[i]=dis[i]=INF;
        t[i]=Marcat[i]=0;
    }
    d[S]=0;
    dis[S]=0;
    add(0,S);
    int j=0;
    while(nh){
        int nc=h[1].s;
        off();
        if(Marcat[nc])
            continue;
        Marcat[nc]=1;
        j++;
        if(j==n){
            nh=0;
            continue;
        }
        for(int i=0;i<Lista[nc].size();i++){
            int nv=Lista[nc][i];
            if(Marcat[nv]==0&&d[nv]>d[nc]+val[nc][nv]+aux[nc]-aux[nv]&&f[nc][nv]<c[nc][nv]){
                d[nv]=d[nc]+val[nc][nv]+aux[nc]-aux[nv];
                add(d[nv],nv);
                dis[nv]=dis[nc]+val[nc][nv];
                t[nv]=nc;
            }
        }
    }
    for(int i=1;i<=n;i++)
        aux[i]=dis[i];
    return d[D]!=INF;
}
void bellmanford(){
    for(int i=1;i<=n;i++)
        d[i]=INF;
    d[S]=0;
    q.push(S);
    Marcat[S]=1;
    while(!q.empty()){
        int nc=q.front();
        q.pop();
        Marcat[nc]=0;
        for(int i=0;i<Lista[nc].size();i++){
            int nv=Lista[nc][i];
            if(d[nv]>d[nc]+val[nc][nv]&&f[nc][nv]<c[nc][nv]){
                d[nv]=d[nc]+val[nc][nv];
                if(Marcat[nv]==0){
                    Marcat[nv]=1;
                    q.push(nv);
                }
            }
        }
    }
}
int main () {
    fin>>n>>m>>S>>D;
    for(i=1;i<=m;i++){
        fin>>x>>y>>cap>>cost;
        Lista[x].push_back(y);
        Lista[y].push_back(x);
        c[x][y]=cap;
        val[x][y]=cost;
        val[y][x]=-cost;
    }
    bellmanford();
    for(i=1;i<=n;i++)
        aux[i]=d[i];
    while(flux()){
    flux();
        mn=INF;
        for(x=D;t[x]>0;x=t[x])
            mn=min(mn,c[t[x]][x]-f[t[x]][x]);
        for(x=D;t[x]>0;x=t[x]){
            f[t[x]][x]+=mn;
            f[x][t[x]]-=mn;
            sol+=val[t[x]][x]*mn;
        }
    }
    fout<<sol<<"\n";
    return 0;
}