Cod sursa(job #1607609)

Utilizator SmarandaMaria Pandele Smaranda Data 21 februarie 2016 14:10:00
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>

using namespace std;

const int N = 55, inf = (1ll << 31) - 1;
vector <int> graph [5003];
int c [5003][5003], a [N], e [N][N], last [5003], f [5003][5003];
int n;
bool used [5003];

void bfs (int s, int d) {
    int x;
    queue <int> q;
    vector <int> :: iterator it;

    memset (used, 0, sizeof (used));
    memset (last, 0, sizeof (last));
    q.push (s);
    used [s] = 1;
    while (!q.empty ()) {
        x = q.front ();
        for (it = graph [x].begin (); it != graph [x].end (); ++ it)
            if ((*it) != d && !used [*it] && c [x][*it] - f [x][*it] > 0) {
                q.push (*it);
                last [*it] = x;
                used [*it] = 1;
            }
        q.pop ();
    }
}

int main () {
    int i, x, y, m, l, s, d, minflow, flow = 0, limita = 0, k, t, j;
    vector <int> :: iterator it;
    bool ok;

    freopen ("algola.in", "r", stdin);
    freopen ("algola.out", "w", stdout);

    scanf ("%d%d", &n, &m);
    for (i = 1; i <= n; i ++) {
        scanf ("%d", &a [i]);
        graph [0].push_back (i);
        graph [i].push_back (0);
        limita += a [i];
        c [0][i] = a [i];
        graph [i].push_back (i + n);
        c [i][i + n] = inf;
    }
    for (i = 1; i <= m; i ++) {
        scanf ("%d%d%d", &x, &y, &l);
        e [x][y] = e [y][x] = l;

        graph [x].push_back (y + n);
        graph [y + n].push_back (x);
        c [x][y + n] = l;

        graph [x + n].push_back (y);
        graph [y].push_back (x + n);
        c [y][x + n] = l;
    }

    s = 0;
    d = n + 1;
    for (t = 1;; t ++) {
        ok = 1;
        while (ok) {
          bfs (0, d);
          ok = 0;
          for (it = graph [d].begin (); it != graph [d].end (); ++ it) {
                y = *it;
              if (f [*it][d] == c [*it][d])
                 continue;
              if (used [*it]) {
                  if (c [*it][d] - f [*it][d] > 0)
                      ok = 1;
                  last [d] = *it;
                  minflow = inf;
                  for (i = d; i != s; i = last [i])
                        minflow = min (minflow, c [last [i]][i] - f [last [i]][i]);
                  if (minflow == 0)
                     continue;
                  flow += minflow;
                  for (i = d; i != s; i = last [i]) {
                       f [last [i]][i] += minflow;
                       f [i][last [i]] -= minflow;
                  }
              }
          }
        }
        if (flow == limita)
            break;
        d += n;
        for (i = 1; i <= n; i ++) {
            graph [i + n * t].push_back (i + n * (t + 1));
            graph [i + n * (t + 1)].push_back (i + n * t);
            c [i + n * t][i + n * (t + 1)] = inf;
            for (j = 1; j <= n; j ++)
                if (e [i][j]) {
                    graph [i + n * t].push_back (j + n * (t + 1));
                    graph [j + n * (t + 1)].push_back (i + n * t);
                    c [i + n * t][j + n * (t + 1)] = e [i][j];
                }
        }
    }
    printf ("%d\n", t);
    return 0;
}