Cod sursa(job #1290740)

Utilizator j.loves_rockJessica Joanne Patrascu j.loves_rock Data 11 decembrie 2014 18:49:12
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.25 kb
#include <cstdio>
#define nmax 360
#include <vector>
//#define inf 0x3f3f3f3f
#include <cstring>
#include <queue>
#include <algorithm>
#include <cassert>

using namespace std;

int price[nmax][nmax],cap[nmax][nmax];
int n,m,s,d,mn;
int dst1[nmax],dst2[nmax],rds[nmax],father[nmax];
bool aq[nmax];
vector <int> graph[nmax];
queue <int> q;
priority_queue <pair<int,int>,vector <pair<int,int> >,greater <pair<int,int> > > heap;
int flow,minprice;

void read(){
    scanf("%d %d %d %d ",&n,&m,&s,&d);
    assert(1 <= n && n <= 350);
    assert(1 <= m && m <= 12500);
    assert(1 <= s && s <= n);
    assert(1 <= d && d <= n);
    assert(s != d);
    int x,y,c,z;
    while(m--){
        scanf("%d %d %d %d ",&x ,&y ,&c ,&z );
        assert(1 <= x && x <= n);
        assert(1 <= y && y <= n);
        assert(x != y && !cap[x][y] && !price[x][y] && !cap[y][x] && !price[y][x]);
        assert(x != d && y != s);
        price[x][y] = z;
        cap[x][y] = c;
        graph[x].push_back(y);
        graph[y].push_back(x);
        assert(1 <= cap[x][y] && cap[x][y] <= 10000);
        assert(-1000 <= price[x][y] && price[x][y] <= 1000);
        price[y][x] = -z;
    }
}

inline bool bellman_ford(){
    flow = minprice = 0;
    memset(dst1,0x3f,sizeof(dst1));
    dst1[s] = 0;
    q.push(s);
    aq[s] = 1;
    int x;
    while(!q.empty()){
        x = q.front();
        q.pop();
        aq[x] = 0;
        for(vector < int > :: iterator it = graph[x].begin() ; it != graph[x].end() ; ++it){
            if(cap[x][*it]){
                if(dst1[*it] > dst1[x] + price[x][*it]){
                    dst1[*it] = dst1[x] + price[x][*it];
                    if(!aq[*it]){
                        q.push(*it);
                        aq[*it] = 1;
                    }
                }
            }
        }
    }
    if(dst1[d] == 0x3f3f3f3f)return 0;
    return 1;
}

inline bool dijkstra(){
    memset(dst2,0x3f,sizeof(dst2));
    int inf1,inf2,aux;
    rds[s] = 0;
    dst2[s] = 0;
    heap.push(make_pair(dst2[s],s));
    while(!heap.empty()){
        inf1 = heap.top().first;
        inf2 = heap.top().second;
        heap.pop();
        if(dst2[inf2] != inf1)continue;
        for(vector < int > :: iterator it = graph[inf2].begin() ; it != graph[inf2].end() ; ++it){
            if(cap[inf2][*it]){
                aux = dst2[inf2] + dst1[inf2] - dst1[*it] + price[inf2][*it];
                if(aux < dst2[*it]){
                    dst2[*it] = aux;
                    rds[*it] = rds[inf2] + price[inf2][*it];
                    father[*it] = inf2;
                    heap.push(make_pair(dst2[*it],*it));
                }
            }
        }
    }
    memcpy(dst1,rds,sizeof(dst1));
    if(dst2[d] == 0x3f3f3f3f)return 0;
    mn = 0x3f3f3f3f;
    for(int i = d ; i != s ; i = father[i]){
        mn = min(mn,cap[father[i]][i]);
    }
    flow += mn;
    minprice += rds[d]*mn;
    for(int i = d ;i != s;i = father[i]){
        cap[father[i]][i] -= mn;
        cap[i][father[i]] += mn;
    }
    return 1;
}

int main(){
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    read();
    bellman_ford();
    while(dijkstra());
    printf("%d\n",minprice);
    return 0;
}