Cod sursa(job #1526889)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 17 noiembrie 2015 16:23:36
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.77 kb
#include<iostream>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<bitset>
#include<cstring>
#include<queue>
#include<stack>

#define ull unsigned long long
#define ll long long
#define pb push_back
#define FOR(a,b,c) for (int a=b;a<=c; ++a)
#define ROF(a,b,c) for (int a=b;a>=c; --a)
#define INF 900500000
#define fson(N) 2*N
#define sson(N) 2*N+1
#define tata(N) N/2

using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int N,M,S,D,aux;
int old_d[360];
int cap[360][360],cost[360][360],flux[360][360],dad[360],dist[360],dist_reala[360];

int H[360],poz[360];

vector<int> v[360];
queue<int> Q;
bitset<360> in_queue;

void sift(int);
void percolate(int);
void bellman_ford();
int dijkstra();

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);
        cost[x][y]=z;
        cost[y][x]=-z;
        cap[x][y]=c;
    }
    bellman_ford();
    int rez=0,costdrum;
    do {
        costdrum=dijkstra();
        rez+=costdrum;
    }
    while (costdrum);
    g<<rez;
    f.close();g.close();
    return 0;
}

void sift(int nod) {
    int son;
    do {
        son=0;
        if (fson(nod)<=aux) {
            son=fson(nod);
            if (sson(nod)<=aux && dist[H[sson(nod)]]<dist[H[son]]) {
                son=sson(nod);
            }
            if (dist[H[son]]>=dist[H[nod]]) {
                son=0;
            }
        }
        if (son) {
            swap(poz[H[nod]],poz[H[son]]);
            swap(H[nod],H[son]);
            nod=son;
        }
    }
    while (son);
}

void percolate(int nod) {
    while (nod>1 && dist[H[tata(nod)]]>dist[H[nod]]) {
        swap(poz[H[nod]],poz[H[tata(nod)]]);
        swap(H[nod],H[tata(nod)]);
        nod=tata(nod);
    }
}

void bellman_ford() {
    FOR (i,1,N) {
        old_d[i]=INF;
    }
    old_d[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]) {
                if (old_d[nod]+cost[nod][*it]<old_d[*it]) {
                    old_d[*it]=old_d[nod]+cost[nod][*it];
                    if (!in_queue.test(*it)) {
                        in_queue.set(*it,1);
                        Q.push(*it);
                    }
                }
            }
        }
        in_queue.set(nod,0);
    }
}

int dijkstra() {
    FOR (i,1,N) {
        dist[i]=INF;
    }
    FOR (i,1,N) {
        H[i]=i;
        poz[i]=i;
    }
    dist[S]=dist_reala[S]=0;
    percolate(S);
    //swap(poz[H[1]],poz[H[S]]);
    //swap(H[1],H[S]);
    aux=N;
    while (aux) {
        int nod=H[1];
        swap(H[1],H[aux]);
        --aux;
        poz[H[1]]=1;
        sift(1);
        if (dist[nod]==INF) {
            continue;
        }
        vector<int>::iterator it;
        for (it=v[nod].begin();it<v[nod].end();++it) {
            int z=old_d[nod]-old_d[*it]+cost[nod][*it];
            if (cap[nod][*it]!=flux[nod][*it] && dist[nod]+z<dist[*it]) {
                dist[*it]=dist[nod]+z;
                dad[*it]=nod;
                dist_reala[*it]=dist_reala[nod]+cost[nod][*it];
                percolate(poz[*it]);
            }
        }
    }
    FOR (i,1,N) {
        old_d[i]=dist_reala[i];
    }
    if (dist[D]!=INF) {
        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_reala[D];
    }
    return 0;
}