Cod sursa(job #2523116)

Utilizator Cezar211Popoveniuc Cezar Cezar211 Data 13 ianuarie 2020 19:31:39
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.55 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");
void read();
int n, m, S, D;
int minn, zmax;
vector<int> v[355];
bitset<355> viz;
bitset<355> muchie[355];
int c[355][355], f[355][355], z[355][355];
int d[355], p[355], cost;
int b[355];
void bellman()
{
    queue<int> q;
    for(int i=1; i<=n; i++)
        b[i] = INT_MAX;
    b[S] = INT_MIN;
    q.push(S);
    while(!q.empty())
    {
        int nod = q.front();
        q.pop();
        for(auto it:v[nod])
            if(b[nod] + z[nod][it] < b[it] && c[nod][it] - f[nod][it] > 0)
            {
                b[it] = b[nod] + z[nod][it];
                q.push(it);
            }
    }
}
bool dijkstra()
{
    for(int i=1; i<=n; i++)
        d[i] = INT_MAX;
    for(int i=1; i<=n; i++)
        viz[i] = 0;
    minn = INT_MAX;
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
    q.push(pair<int,int>(0, S));
    d[S] = INT_MIN;
    while(!q.empty())
    {
        int nod = q.top().second;
        q.pop();
        if(viz[nod])
            continue;
        viz[nod] = 1;
        for(auto it:v[nod])
            if(!viz[it] && d[nod] + z[nod][it] < d[it] &&
                    c[nod][it] - f[nod][it] > 0)
            {
                d[it] = d[nod] + z[nod][it];
                p[it] = nod;
                q.push(pair<int,int>(d[it], it));
            }
    }
    if(d[D] == INT_MAX)
        return 0;
    int nod = D;
    vector<pair<int,int>> edges;
    while(p[nod])
    {
        minn = min(minn, c[p[nod]][nod]-f[p[nod]][nod]);
        edges.push_back(pair<int,int>(p[nod], nod));
        nod = p[nod];
    }
    for(auto it:edges)
    {
        f[it.first][it.second]+=minn;
        f[it.second][it.first]-=minn;
        cost+=minn*(z[it.first][it.second]-zmax);
    }
    return 1;
}
int main()
{
    read();
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(muchie[i][j])
                z[i][j]+=zmax;
    for(int i=1;  i<=n; i++)
        for(int j=1; j<=n; j++)
            if(z[i][j] < 0)
    {
        cout << "WTF";
    }
    while(dijkstra());
    fout << cost;

    return 0;
}
void read()
{
    fin >> n >> m >> S >> D;
    for(int i=1; i<=m; i++)
    {
        int x, y, C, Z;
        fin >> x >> y >> C >> Z;
        muchie[x][y] = muchie[y][x] = 1;
        zmax = max(zmax, abs(Z));
        v[x].push_back(y);
        v[y].push_back(x);
        c[x][y] = C;
        z[x][y] = Z;
        z[y][x] = -Z;
    }
}