Cod sursa(job #2964399)

Utilizator Ruxi_GontescuGontescu Maria Ruxandra Ruxi_Gontescu Data 12 ianuarie 2023 21:53:54
Problema Taramul Nicaieri Scor 100
Compilator cpp-64 Status done
Runda Teme Pregatire ACM Unibuc 2014, Anul I, Semestrul 2 Marime 2.88 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

ifstream fin("harta.in");
ofstream fout("harta.out");
int n, m, x, y, capacitate, mat[1001][1001];
queue <int> q;
bool visited[1001];
int parinte[1001];
bool bfs() {
    while (!q.empty())
        q.pop();

    for (int i = 0; i <= 2 * n + 1; ++i) {
        parinte[i] = -1;
        visited[i] = false;
    }
    q.push(0);
    visited[0] = true;

    while (!q.empty()) {
        int nod = q.front();
        q.pop();

        if (nod == 2 * n + 1)
            return true;

        for (int i = 1; i <= 2 * n + 1; ++i)
            if (visited[i] == false && mat[nod][i] > 0) {
                q.push(i);
                visited[i] = true;
                parinte[i] = nod;
            }
    }

    return false;
}
int fluxMax(){
    int maxFlow = 0;
    vector<int> drum;
    // cat timp exista drumuri de ameliorare
    while (bfs()){
        // ne uitam in jumatatea de jos a matricei, unde pe ultima coloana avem gradele interne
        for (int i=n+1; i<2*n+1; i++){
            if (mat[i][2*n+1]>0 && visited[i]==true){
                int frunza = i;
                drum.clear();
                drum.push_back(2*n+1);
                drum.push_back(frunza);

                int nod = parinte[frunza];

                if (nod == 0)
                    drum.push_back(nod);
                else {
                    while (nod != 0){
                        drum.push_back(nod);
                        nod = parinte[nod];
                    }
                    drum.push_back(0);
                }
                for (auto elem : drum)
                    cout << elem << " ";
                cout << endl;
                reverse(drum.begin(), drum.end());
                int minCap = 2e9;
                for (int i = 0; i < drum.size() - 1; i++)
                    minCap = min(minCap, mat[drum[i]][drum[i+1]]);
                maxFlow += minCap;
                for (int i = 0; i < drum.size() - 1; i++) {
                    mat[drum[i]][drum[i + 1]] -= minCap;
                    mat[drum[i + 1]][drum[i]] += minCap;
                }
            }
        }
    }
    return maxFlow;
}
int main() {
    // se da nr de orase
    fin >> n;
    int i,nod;
    for (i=1; i<=n; i++){
        fin >> x >> y;
        mat[0][i] = x;  // pe linia 0 avem gradul extern al orasului i
        mat[n+i][2*n+1] = y;  // pe ultima coloana, liniile n+i avem gradele interne
        for (nod = 1; nod <= n; nod ++)
            if (nod != i)
                mat[i][n+nod] = 1;
    }
    for (i=0; i<=n+n; i++){
        for (nod=0; nod <=2*n+1; nod ++)
            cout << mat[i][nod] << " ";
        cout << endl;
    }
    fout << fluxMax() << endl;

    for ( i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (mat[i][n + j] == 0 && i != j)
                fout << i << " " << j << endl;
    return 0;
}