Cod sursa(job #2957774)

Utilizator iulia.talpalariuIulia-Georgiana Talpalariu iulia.talpalariu Data 23 decembrie 2022 14:39:28
Problema Taramul Nicaieri Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.52 kb
#include <vector>
#include <queue>
#include <fstream>
#include <climits>
#include <iostream>
using namespace std;
ifstream fileIn("harta.in");
ofstream fileOut("harta.out");


class Graph {
protected:
    int N;
    int M;
    vector<int> prev_in_bfs;
    vector<vector<int>> list_adj;
    vector<bool> visited;
    vector<vector<int>> capacities;


public:
    virtual void read();
    void initialize(int k, int initial_capacity = 0);
    int bfs(int s, int t);
    int maxflow(int source, int target);
    int getNoNodes() const{
        return N;
    }

};

void Graph::initialize(int k, int initial_capacity) {
    list_adj.resize(k);
    visited.resize(k);
    prev_in_bfs.resize(k);
    capacities.resize(k);

    for(int i = 0; i < (int) capacities.size(); ++i) {
        capacities[i].resize(k, initial_capacity);
    }
}

void Graph:: read() {
    fileIn >> N >> M;
    initialize(N+1);

    int a, b, c;
    for(int i=1; i<= M; i++) {
        fileIn >> a >> b >> c;
        list_adj[a].push_back(b);
        list_adj[b].push_back(a);
        capacities[a][b] = c;
    }

}

int Graph::bfs(int s, int t) {
    //filling prev and visited vectors with default values
    fill(prev_in_bfs.begin(), prev_in_bfs.end(), -2);
    fill(visited.begin(), visited.end(), false);
    // queue for bfs
    queue<pair<int,int>> q_bfs;

    //visiting the start node and adding to the queue
    q_bfs.emplace(s, INT_MAX);

    visited[s] = true;
    prev_in_bfs[s] = -1;
    int bottleneck;

    while(!q_bfs.empty()) {
        auto curr = q_bfs.front();
        int curr_node = curr.first;
        int curr_flow = curr.second;
        q_bfs.pop();

        for( auto node: list_adj[curr_node]) {
            // for every adj node
            int flow = capacities[curr_node][node];
            if(!visited[node] && flow > 0) { // if the node it s not visited in this bfs and the edge have capacity
                //we visit it and set its prev node
                visited[node] = true;
                prev_in_bfs[node] = curr_node;
                //we calculate bottleneck as minimum on the current path from source to target
                bottleneck = min(curr_flow, flow);
                if (node ==  t) {
                    return bottleneck;
                }
                q_bfs.emplace(node, bottleneck);
            }
        }

    }
    return 0;

}

int Graph::maxflow(int source, int target) {
    int flow = 0;

    int bottleneck;

    bottleneck = bfs(source,target);

    while(bottleneck !=0) {
        flow += bottleneck;
        // traverse the path in reverse order to update capacity
        for(int curr_node = target; curr_node != source; curr_node = prev_in_bfs[curr_node]) {
            capacities[prev_in_bfs[curr_node]][curr_node] -= bottleneck; //decreasing forward edge capacity
            capacities[curr_node][prev_in_bfs[curr_node]] += bottleneck; // increasing the reversed edge capacity
        }

        bottleneck = bfs(source, target);
    }
    return flow;
}



class Cuplaj2: public Graph {
    //int E;

public:
    void read() override;
    void display_path();

};

void Cuplaj2 ::read() {
    fileIn >> N ;
    initialize(2 * N + 2, 0);
    int start = 0;
    int target = 2 * N +1;
    int a, b;
    for(int i = 1; i <= N; ++i) {
        fileIn >> a >> b;
        // de la start la i cu costul a
        list_adj[start].push_back(i);
        list_adj[i].push_back(0);
        capacities[start][i] = a;

        //de la i la toate fara i cu costul 1
        for(int j = N + 1; j <= 2 * N ; ++j) {
            if (i == j - N) continue;
            list_adj[i].push_back(j);
            list_adj[j].push_back(i);
            capacities[i][j] = 1;
        }

        //de la N + i la target cu costul b
        list_adj[N + i].push_back(target);
        list_adj[target].push_back(N + i);
        capacities[N + i][target] = b;
    }
}

void Cuplaj2::display_path() {
    int start = 0, target = 2 * N + 1;
    fileOut << maxflow(start, target)<<'\n';
    queue<int> q;
    q.push(start);

    for(auto elem_first_partition: list_adj[start]) {
        for(auto elem_snd_partition: list_adj[elem_first_partition]){

            if (elem_snd_partition == start) {

                continue;
            }

            if (capacities[elem_first_partition][elem_snd_partition] == 0) {

                fileOut << elem_first_partition << ' ' <<elem_snd_partition - N<< '\n';
                capacities[elem_first_partition][elem_snd_partition]++;

            }
        }
    }
}




int main()  {
    Cuplaj2 my_graph;
    my_graph.read();
    my_graph.display_path();


    return 0;

}