Cod sursa(job #3188102)

Utilizator AnastasiaStefanescuAnastasia Stefanescu AnastasiaStefanescu Data 1 ianuarie 2024 17:41:13
Problema Taramul Nicaieri Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <fstream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

ifstream fin("harta.in");
ofstream fout("harta.out");

#define maxdim 203
#define max_sum_muchii 16000

int n, in[103], out[103];
int flux[maxdim][maxdim], flux_total;
int rezidual[maxdim][maxdim];
int parinte[maxdim];
int ult_nod, primul_nod, capacitate_reziduala;
vector<int> drum;
queue<int> q;

struct muchie_spre_copil{
    int copil, capacit, flux_crt;
};

vector<vector<muchie_spre_copil>> adiac_cu_flux;
vector<vector<muchie_spre_copil>> graf_rezidual;

void determ_drum_inapoi()
{
    int nod = ult_nod, prev;
    
    drum.clear();
    capacitate_reziduala = max_sum_muchii;
    while(nod != primul_nod)
    {
        drum.push_back(nod);
        prev = parinte[nod];
        if(rezidual[prev][nod] < capacitate_reziduala)
            capacitate_reziduala = rezidual[prev][nod];
        nod = prev;
    }
    drum.push_back(nod);
    reverse(drum.begin(), drum.end());
}

int exista_drum_crestere(){
    vector<int> viz(maxdim, 0);
    queue <int> qu;
    
    qu.push(0);
    viz[0] = 1;
    parinte[0] = -1;
    
    while (!qu.empty()) {
           int nod = qu.front();
           qu.pop();

           for (int nod2 = 1; nod2 <= 2*n+1; nod2++)
           {
               if (viz[nod2] == 0 && rezidual[nod][nod2] > 0)
               {
                   // Daca gasim conexiune la final, se termina bfs
                   if (nod2 == 2*n+1) {
                       parinte[nod2] = nod;
                       
                       determ_drum_inapoi();
                       return 1;
                   }
                   qu.push(nod2);
                   parinte[nod2] = nod;
                   viz[nod2] = 1;
               }
           }
       }
    return 0;
}

int main()
{
    //nodul de start n punem 0, finalul este n+1
    int i,j;
    
    fin >> n;
    ult_nod = 2*n+1;
    primul_nod = 0;
    for (i = 1; i<= n; i++)
        fin >> out[i] >> in[i];
    
    for(i = 1; i<= n; i++) //primul rand de noduri
    {
        rezidual[primul_nod][i] = out[i];
        
        for (j = n+1; j<= 2*n; j++)
            if(j - n != i)
            {
                rezidual[i][j] = 1;
            }
        
        rezidual[n+i][ult_nod] = in[i];
    }
    
    while (exista_drum_crestere()) 
    {
        //am calculat deja capacitatea reziduala
                     
        //updatam fluxul pe drumul gasit
        for (i = 0; i< drum.size()-1; i++)
        {
            int nod = drum[i];
            int nod2 = drum[i+1];
            flux[nod][nod2] += capacitate_reziduala;
            rezidual[nod][nod2] -= capacitate_reziduala;
        }
                     
        flux_total += capacitate_reziduala;
    }
    
    fout << flux_total;
    
    
}