Cod sursa(job #2489992)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 9 noiembrie 2019 15:49:58
Problema Pixels Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.89 kb
#include <fstream>
#include <vector>
#include <deque>
#define DIM 10010
#define INF 2000000000
using namespace std;

ifstream fin ("pixels.in");
ofstream fout ("pixels.out");
struct muchie{
    int x,y,capacitate;
};
vector < pair<int,int> > L[DIM],edges[DIM];
vector <muchie> mch;
deque <int> c;
int A[DIM],B[DIM],dist[DIM];
int di[] = {-1,0,1,0};
int dj[] = {0, 1,0,-1};
int n,i,j,cod1,cod2,sursa,dest,total,poz,cost;
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=0;i<=n*n+1;i++){
        edges[i].clear();
        dist[i] = INF;
    }
    c.clear();
    c.push_back(sursa);
    dist[sursa] = 0;
    while (!c.empty()){
        int nod = c.front();
        c.pop_front();
        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.push_back(vecin);
            }
            if (dist[vecin] == 1+dist[nod])
                edges[nod].push_back(make_pair(vecin,poz));
        }}}
int dfs (int nod, int dest, int max_flow){
    if (nod == dest)
        return max_flow;
    if (!max_flow)
        return 0;
    int flow = 0;
    for (int i=0;i<edges[nod].size();i++){
        int vecin = edges[nod][i].first;
        int poz = edges[nod][i].second;
        if (!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 get_max_flow (int sursa, int dest){

    int flux = 0, sol = 0;
    do{
        bfs (sursa,dest);
        flux = dfs (sursa,dest,INF);
        sol += flux;
    } while (flux);

    return sol;
}
int main (){

    fin>>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;
    for (i=1;i<=n*n;i++){
        fin>>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<=n*n;i++){
        fin>>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;
                int iv = i+di[dir];
                int jv = j+dj[dir];
                if (inmat(iv,jv) && (dir == 1 || dir == 2)){
                    /// o sa il pe i,j doar de doua ca sa nu pun mai multe muchii de doua ori
                    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
    fout<<total - get_max_flow(sursa,dest);

    return 0;
}