Cod sursa(job #556677)

Utilizator DraStiKDragos Oprica DraStiK Data 16 martie 2011 11:34:55
Problema Pixels Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;

#define pb push_back

#define INF 0x3f3f3f3f
#define DIM 10005

vector <int> g[DIM],c[DIM],f[DIM];
map <int,int> poz[DIM];
int N,SRC,DST,nrt;
queue <int> q;
bool viz[DIM];
int t[DIM];

void read ()
{
    int i,x,y,z,t;

    scanf ("%d",&N);
    SRC=0; DST=N*N+1;

    for (i=1; i<=N*N; ++i)
    {
        scanf ("%d",&x);

        g[SRC].pb (i); g[i].pb (SRC);
        c[SRC].pb (x); c[i].pb (0);
        f[SRC].pb (0); f[i].pb (0);

        poz[SRC][i]=g[SRC].size ()-1;
        poz[i][SRC]=g[i].size ()-1;
        nrt+=x;
    }

    for (i=1; i<=N*N; ++i)
    {
        scanf ("%d",&x);

        g[i].pb (DST); g[DST].pb (i);
        c[i].pb (x); c[DST].pb (0);
        f[i].pb (0); f[DST].pb (0);

        poz[DST][i]=g[DST].size ()-1;
        poz[i][DST]=g[i].size ()-1;
        nrt+=x;
    }

    for (i=1; i<=N*N; ++i)
    {
        scanf ("%d%d%d%d",&x,&y,&z,&t);

        if (i>N)
        {
            g[i].pb (i-N); g[i-N].pb (i);
            c[i].pb (x); c[i-N].pb (x);
            f[i].pb (0); f[i-N].pb (0);

            poz[i-N][i]=g[i-N].size ()-1;
            poz[i][i-N]=g[i].size ()-1;
        }
        if (i%N!=1)
        {
            g[i].pb (i-1); g[i-1].pb (i);
            c[i].pb (t); c[i-1].pb (t);
            f[i].pb (0); f[i-1].pb (0);

            poz[i-1][i]=g[i-1].size ()-1;
            poz[i][i-1]=g[i].size ()-1;
        }
    }
}

inline int bf ()
{
    int i,nod;

    memset (viz,0,sizeof (viz));
    memset (t,0,sizeof (t));

    viz[SRC]=1;
    for (q.push (SRC); !q.empty (); q.pop ())
    {
        nod=q.front ();
        for (i=0; i<(int)g[nod].size (); ++i)
            if (!viz[g[nod][i]] && f[nod][i]<c[nod][i])
            {
                viz[g[nod][i]]=1;
                t[g[nod][i]]=nod;
                if (g[nod][i]!=DST)
                    q.push (g[nod][i]);
            }
    }

    if (!viz[DST])
        return 0;
    return 1;
}

void solve ()
{
    int nrmin,i,nod,ind;

    while (bf ())
    {
        for (i=0; i<(int)g[DST].size (); ++i)
            if (t[g[DST][i]]!=-1)
            {
                ind=poz[g[DST][i]][DST];
                if (c[g[DST][i]][ind]!=f[g[DST][i]][ind])
                {
                    t[DST]=g[DST][i]; nrmin=INF;
                    for (nod=DST; nod!=SRC; nod=t[nod])
                    {
                        ind=poz[t[nod]][nod];
                        nrmin=min (nrmin,c[t[nod]][ind]-f[t[nod]][ind]);
                    }
                    for (nod=DST; nod!=SRC; nod=t[nod])
                    {
                        ind=poz[t[nod]][nod];
                        f[t[nod]][ind]+=nrmin;

                        ind=poz[nod][t[nod]];
                        f[nod][ind]-=nrmin;
                    }
                    nrt-=nrmin;
                }
            }
    }

    printf ("%d",nrt);
}

int main ()
{
    freopen ("pixels.in","r",stdin);
    freopen ("pixels.out","w",stdout);

    read ();
    solve ();

    return 0;
}