Cod sursa(job #1157133)

Utilizator PatrikStepan Patrik Patrik Data 28 martie 2014 11:45:28
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.69 kb
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<queue>
    #include<set>
    using namespace std;
    #define NMAX 351
    #define pb push_back
    #define inf 500001
    int N , M ,S, D , cap[NMAX][NMAX] , f[NMAX][NMAX] , u[NMAX];
    int t[NMAX] ,old_d[NMAX] , real_d[NMAX] , new_d[NMAX] , rez;
    struct comp{
        bool operator()(int a , int b)
        {
            return new_d[a] < new_d[b];
        }
    };
    bool inq[NMAX];
    vector<int> G[NMAX] , cost[NMAX];
    queue<int> q;
    multiset<int,comp> Q;

    void read();
    void solve();
    void write();
    void bellman();
    bool dijkstra();

    int main()
    {
        read();
        solve();
        write();
        return 0;
    }

    void read()
    {
        int x , y , c , z;
        freopen("fmcm.in" , "r" , stdin );
        scanf("%d%d%d%d" , &N , &M, &S , &D );
        for(int i = 1 ; i <= M ; ++i )
        {
            scanf("%d%d%d%d" , &x , &y , &c , &z);
            G[x].pb(y);
            cost[x].pb(z);
            G[y].pb(x);
            cost[y].pb(-z);
            cap[x][y] = c;
        }
    }

    void solve()
    {
        int fmin;
        bellman();
        while(dijkstra())
        {
                int nod = D;
                fmin = inf;
                for(;nod!=S;nod = t[nod])
                    fmin = min(fmin,cap[t[nod]][nod]-f[t[nod]][nod]);
                if(fmin)
                {
                    for(nod = D; nod != S; nod = t[nod])
                    {
                        f[t[nod]][nod] += fmin;
                        f[nod][t[nod]] -=fmin;
                    }
                    rez += real_d[D]*fmin;
                }
        }
    }

    void bellman()
    {
        memset(old_d,inf,sizeof(old_d));
        q.push(S);
        inq[S] = 1;
        old_d[S] = 0;
        while(!q.empty())
        {
            int nod = q.front();
            q.pop();
            if(nod == D)continue;
            if(!inq[nod])continue;
            inq[nod] = 0;
            for(int i = 0 ; i < (int)G[nod].size() ; ++i )
            {
                if(G[nod][i] == t[nod])continue;
                int w = G[nod][i];
                if(cap[nod][w] && old_d[nod] + cost[nod][i] < old_d[w])
                {
                    old_d[w] = old_d[nod] + cost[nod][i];
                    if(!inq[w])
                    {
                        inq[w] = 1;
                        q.push(w);
                    }
                    t[w] = nod;
                }
            }
        }
    }

    bool dijkstra()
    {
        for(int i  = 1 ; i <= N ; ++i )new_d[i] = inf;
        memset(inq,0,sizeof(inq));
        new_d[S] = 0;inq[S] = 1;
        Q.insert(S);
        while(!Q.empty())
        {
            int nod = *Q.begin();
            Q.erase(Q.begin());
            if(nod == D)continue;
            if(!inq[nod])continue;
            inq[nod] = 0;
            for(int i  = 0 ; i <(int)G[nod].size() ; ++i )
            {
                int w = G[nod][i];
                if(w == t[nod])continue;
                if(f[nod][w] < cap[nod][w] &&
                   new_d[nod] + cost[nod][i] + old_d[nod]-old_d[w] < new_d[w])
                {
                    new_d[w] = new_d[nod] + cost[nod][i] + old_d[nod]-old_d[w];
                    t[w] = nod;
                    inq[w] = 1;
                    Q.insert(w);
                    real_d[w] = real_d[nod] + cost[nod][i];
                }
            }
        }
        return new_d[D] != inf;
    }

    void write()
    {
        freopen("fmcm.out" , "w" , stdout );
        printf("%d" , rez );
    }