Cod sursa(job #2490600)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 10 noiembrie 2019 16:00:44
Problema Pixels Scor 90
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 3.92 kb
#include <cstdio>
#include <vector>
#include <deque>
#include <cstring>
#define DIM 10010
#define INF 2000000000
using namespace std;

//ifstream fin ("pixels.in");
//ofstream fout ("pixels.out");
FILE *fin = fopen ("pixels.in","r");
FILE *fout = fopen ("pixels.out","w");
struct muchie{
    int x,y,capacitate;
};
vector < pair<int,int> > L[DIM],edges[DIM];
vector <muchie> mch;

int A[DIM],B[DIM],dist[DIM],c[2*DIM],w[DIM*2];
int di[] = {-1,0,1,0};
int dj[] = {0, 1,0,-1};
int n,i,j,cod1,cod2,sursa,dest,total,poz,cost,m;
inline int get_cod (int i, int j){
    return (i-1)*n+j;
}
inline int inmat (int i, int j){
    if (i >= 1 && i <= n && j >= 1 && j <= n)
        return 1;
    return 0;
}
void bfs (int sursa, int dest){
    for (int i=sursa;i<=dest;++i)
        dist[i] = INF;
    int p = 1, u = 1;
    c[p] = sursa;
    dist[sursa] = 0;
    while (p <= u){
        int nod = c[p];
        p++;
        if (nod == dest)
            break;
        for (int i=0;i<L[nod].size();++i){
            int vecin = L[nod][i].first;
            int poz = L[nod][i].second;
            if (!mch[poz].capacitate)
                continue;

            if (dist[vecin] == INF){
                dist[vecin] = 1+dist[nod];
                c[++u] = vecin;
            }}}}
int dfs (int nod, int dest, int max_flow){
    if (nod == dest)
        return max_flow;
    if (!max_flow)
        return 0;
    int flow = 0;
    for (;w[nod]<L[nod].size();w[nod]++){
        int vecin = L[nod][w[nod]].first;
        int poz = L[nod][w[nod]].second;
        if (dist[vecin] != dist[nod]+1 || !mch[poz].capacitate)
            continue;

        int val = dfs (vecin,dest,min(mch[poz].capacitate,max_flow-flow));
        mch[poz].capacitate -= val;
        mch[poz^1].capacitate += val; /// muchia inversa
        flow += val;
    }
    return flow;
}

int main (){

    //fin>>n;
    fscanf (fin,"%d",&n);
    /// pun muchie intre sursa si toate nodurile de capacitate a[i][j]
    /// si intre toate nodurile si destinatie
    sursa = 0, dest = n*n+1, m = n*n;
    for (i=1;i<=m;++i){
        fscanf (fin,"%d",&A[i]);
        /// muchie de la sursa la i
        mch.push_back({sursa,i,A[i]});
        poz = mch.size()-1;
        L[sursa].push_back(make_pair(i,poz)); /// mai retin si pozitia in vectorul de muchii

        mch.push_back({i,sursa,0}); /// muchia inversa de capacitate 0
        L[i].push_back(make_pair(sursa,poz+1));

        total += A[i];
    }

    for (i=1;i<=m;++i){
        //fin>>B[i];
        fscanf (fin,"%d",&B[i]);
        mch.push_back({i,dest,B[i]});
        poz = mch.size()-1;
        L[i].push_back(make_pair(dest,poz));

        mch.push_back({dest,i,0});
        L[dest].push_back(make_pair(i,poz+1));

        total += B[i];
    }

    /// pun muchii intre noduri si capaciatate pijk

    for (i=1;i<=n;++i)
        for (j=1;j<=n;++j){
            cod1 = get_cod (i,j);
            for (int dir=0;dir<=3;++dir){
                //fin>>cost;
                fscanf (fin,"%d",&cost);
                int iv = i+di[dir];
                int jv = j+dj[dir];
                if ((dir == 1 || dir == 2) && inmat(iv,jv)){
                    cod2 = get_cod (iv,jv);
                    /// aici am muchie orientata
                    mch.push_back({cod1,cod2,cost});
                    poz = mch.size()-1;
                    L[cod1].push_back(make_pair(cod2,poz));

                    mch.push_back({cod2,cod1,cost});
                    L[cod2].push_back(make_pair(cod1,poz+1));
                }}}


    /// sum aij + sum bij - sum pij => trb sa minimizez pij => taietura
    int flux = 0, sol = 0;
    do{
        memset (w,0,sizeof w);
        bfs (sursa,dest);
        flux = dfs (sursa,dest,total);
        sol += flux;
    } while (flux);

    //fout<<total - sol;
    fprintf(fout,"%d",total-sol);
    return 0;
}
/// m am saturat sa optimizez pb asta