Cod sursa(job #1993005)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 22 iunie 2017 08:48:02
Problema Pixels Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.95 kb
#include <cstdio>
#include <algorithm>
#include <vector>

#define INF 1000000000

#define MAXN 100
#define MAXD 10002
#define MAXK 60000

#define NRDIR 4
int dl[NRDIR] = {-1, 0, 1, 0};
int dc[NRDIR] = {0, 1, 0, -1};

struct myc {
    int x, y;
    myc(int _x, int _y) {
        x = _x;
        y = _y;
    }
};

std::vector <myc> g[MAXD];
int c[MAXK + 1], f[MAXK + 1];
int q[MAXD], from[MAXD], cine[MAXD];
bool viz[MAXD];
int care[MAXN][MAXN];
int k;

FILE *fin = fopen("pixels.in", "r"), *fout = fopen("pixels.out", "w");

inline void adauga(int x, int y, int z) {
    c[k] = z;
    g[x].push_back(myc(y, k));
    k++;

    c[k] = z;
    g[y].push_back(myc(x, k));
    k++;
}

inline bool bfs(int s, int d) {
    for (int i = s; i <= d; i++)
        cine[i] = from[i] = viz[i] = 0;
    viz[s] = 1;
    int st = 0, dr = 1;
    q[1] = s;

    while (viz[d] == 0 && st < dr) {
        int x = q[st++];
        for (auto &y : g[x]) {
            if (viz[y.x] == 0 && c[y.y] > f[y.y]) {
                viz[y.x] = 1;
                from[y.x] = x;
                cine[y.x] = y.y;
                q[dr++] = y.x;
            }
        }
    }

    return viz[d];
}

inline int taiMin(int s, int d) {
    int ans = 0;
    while(bfs(s, d)) {
        for (auto &x : g[d]) {
            if (viz[x.x] && c[1 ^ x.y] > f[1 ^ x.y]) {
                from[d] = x.x;
                cine[d] = 1 ^ x.y;
                int u = INF, y = d;
                while (y != s) {
                    u = std::min(u, c[cine[y]] - f[cine[y]]);
                    y = from[y];
                }
                y = d;
                while (y != s) {
                    f[cine[y]] += u;
                    f[1 ^ cine[y]] -= u;
                    y = from[y];
                }
                ans += u;
            }
        }
    }
    return ans;
}

int main() {
    int n;
    fscanf(fin, "%d", &n);

    int s = 0, d = 2 + n * n, o = 0, ans = 0;

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            care[i][j] = ++o;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int x;
            fscanf(fin, "%d", &x);

            ans += x;

            adauga(s, care[i][j], x);
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int x;
            fscanf(fin, "%d", &x);

            ans += x;

            adauga(care[i][j], d, x);
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int p = 0; p < NRDIR; p++) {
                int x;
                fscanf(fin, "%d", &x);

                if (x != 0 && (p == 1 || p == 2))
                    adauga(care[i][j], care[i + dl[p]][j + dc[p]], x);
            }
        }
    }

    ans -= taiMin(s, d);

    fprintf(fout, "%d\n", ans);

    fclose(fin);
    fclose(fout);
    return 0;
}