Cod sursa(job #1347029)

Utilizator somuBanil Ardej somu Data 18 februarie 2015 19:12:51
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define nmax 1005

using namespace std;

ifstream fin("maxflow.in");
ofstream fout("maxflow.out");

int n, m, fMax = 0;
int c[nmax][nmax], f[nmax][nmax], t[nmax];
bool viz[nmax];
vector <int> G[nmax];
queue <int> q;

void read() {
    int x,y,z;
    fin >> n >> m;
    for (int i = 1; i <= m; i++) {
        fin >> x >> y >> z;
        G[x].push_back(y);
        G[y].push_back(x);
        c[x][y] += z;
    }
}

int bfs() {
    
    // ideea e urmatoarea: Prin functia asta verific daca este sau nu
    // drum de la sursa la destinatie format din muchii nenule, adica
    // care au costul muchiei - costul fluxului de pe acea muchie
    // mai mare ca 0. Daca avem un drum bfs returneaza true daca nu false
    
    for (int i = 1; i <= n; i++)
        viz[i] = 0;
    
    viz[1] = 1;
    q.push(1);
    
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        if (nod == n) continue;
        for (int i = 0; i < G[nod].size(); i++) {
            int vecin = G[nod][i];
            if (viz[vecin] || c[nod][vecin] == f[nod][vecin]) continue;
            t[vecin] = nod;
            viz[vecin] = true;
            q.push(vecin);
        }
    }
    
    return viz[n];
    
}

void solve() {
    // Flux maxim: DINIC
    // Verificam de la destinatie spre sursa, muchia de cost minim
    // costul acesta nu este neaparat costul muchiei, ci
    // diferenta dintre costul muchiei si fluxul muchiei
    // aceasta diferenta (minima) va fi fluxul minim care va fi adunat
    // la fluxul maxim final. Daca am gasit o astfel de muchie minima
    // updatam fluxurile tuturor muchiilor de pe drumu respectiv
    // la final afisam fMax.
    
    while (bfs()) {
        for (int i = 0; i < G[n].size(); i++) {
            int vecin = G[n][i];
            if (!viz[vecin] || c[vecin][n] == f[vecin][n]) continue;
            
            t[n] = vecin;
            
            int fMin = 110005;
            
            for (int nod = n; nod != 1; nod = t[nod])
                if (fMin > c[t[nod]][nod] - f[t[nod]][nod])
                    fMin = c[t[nod]][nod] - f[t[nod]][nod];
            
            if (fMin == 0) continue;
            
            fMax += fMin;
            
            for (int nod = n; nod != 1; nod = t[nod])
                f[t[nod]][nod] += fMin,
                f[nod][t[nod]] -= fMin;
        }
    }
    fout << fMax << "\n";
}

int main() {
    
    read();
    solve();
    
    fin.close();
    fout.close();
    
    return 0;
}