Cod sursa(job #1513527)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 29 octombrie 2015 17:52:09
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 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 2000000000

// algoritmul neoptimizat cu bellman-ford

using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int N,M,S,D,nr;
int cap[360][360],flux[360][360],cost[360][360],dist[360],dad[360];
// cap[i][j]=capacitatea muchiei (i,j);
// flux[i][j]=fluxul muchiei (i,j) la un moment dat;
// cost[i][j]=costul muchiei (i,j);
// dist[i]=costul total de la sursa la nodul i la un moment dat
// dad[i]=nodul precedent nodului i la un moment dat

vector<int> v[360];

int bellman_ford();

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);
        cap[x][y]=c;
        cost[x][y]=z;
        cost[y][x]=-z;
    }
    int costdrum,rez=0;
    do { // cat timp gasesc un drum de avansare, adaug costul acestuia la costul total
        costdrum=bellman_ford();
        rez+=costdrum;
    }
    while(costdrum);
    g<<rez;
    f.close();g.close();
    return 0;
}

int bellman_ford() { // caut un drum de avansare de cost minim
    FOR (i,1,N) {
        dist[i]=INF;
        dad[i]=-1;
    }
    dist[S]=0;
    bool ok=true;
    while (ok) {
        ok=0;
        FOR (i,1,N) {
            vector<int>::iterator it;
            for (it=v[i].begin();it<v[i].end();++it) {
                if (cap[i][*it]!=flux[i][*it] && dist[i]+cost[i][*it]<dist[*it]) {
                    dist[*it]=dist[i]+cost[i][*it];
                    dad[*it]=i;
                    ok=1;
                }
            }
        }
    }
    ++nr;
    if (dist[D]<INF-12500000) {
        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[D];
    }
    return 0;
}