Cod sursa(job #3186639)

Utilizator Matoka26Dogaru Mihail Danut Matoka26 Data 24 decembrie 2023 02:29:16
Problema Taramul Nicaieri Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.74 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

#define INF 2147483647
using namespace std;



class MaxFlowGraph{
private:
    ///ATTRIBUTES
    vector<vector<int>>adjacency;
    vector<vector<int>>capacity;
    vector<vector<int>>flow;

    ///METHODS
    int bfs(const int& s, const int& t, vector<int>& parent);
    void printMatrix(const vector<vector<int>> &m);

public:
    MaxFlowGraph(const vector<vector<int>>& adjacency, const vector<vector<int>>& capacity);
    int maxFlow(const int& s, const int& t);
    vector<vector<int>>& getFlow();

    void printCapacity();
    void printAdjacency();
    void printFlow();


};

MaxFlowGraph::MaxFlowGraph(const vector<vector<int>>& adjacency, const vector<vector<int>>& capacity){
        this->adjacency = adjacency;
        this->capacity = capacity;
        this->flow = vector<vector<int>> (this->capacity.size(), vector<int>(this->capacity.size(),0));

}

void MaxFlowGraph::printMatrix(const vector<vector<int>> &m){
    for(int i = 0 ; i < m.size() ; i++){
        cout<<i<<':';
        for(int j = 0 ; j < m[i].size() ; j++)
            cout<<m[i][j]<<" ";
        cout<<'\n';
    }
}

void MaxFlowGraph::printAdjacency(){
    printMatrix(this->adjacency);
}

void MaxFlowGraph::printCapacity(){
    printMatrix(this->capacity);
}
void MaxFlowGraph::printFlow(){
    printMatrix(this->flow);
}

vector<vector<int>>& MaxFlowGraph::getFlow(){
    return this->flow;
}


int MaxFlowGraph::bfs(const int& s, const int& t, vector<int>& parent){
    fill(parent.begin(), parent.end(), -1);
    parent[s] = -2;

    queue<pair<int,int>>q;
    q.push({s,INF});

    while(!q.empty()){
        int current = q.front().first;
        int flow = q.front().second;
        q.pop();

        for(int next : this->adjacency[current]){
            if(parent[next] == -1 && this->capacity[current][next] > this->flow[current][next]){
                parent[next] = current;
                int newFlow = min(flow, this->capacity[current][next] - this->flow[current][next]);
                if(next == t)
                    return newFlow;
                q.push({next, newFlow});
            }

        }
    }
    return 0;
}

int MaxFlowGraph::maxFlow(const int& s, const int& t){
    vector<int>parent(this->capacity.size());
    int flowFound = 0;

    while(1){
        int newFlow = bfs(s,t,parent);

        if(!newFlow)
            break;

        flowFound += newFlow;
        int current = t;
        while(current != s){
            int dad = parent[current];
            flow[current][dad] -= newFlow;
            flow[dad][current] += newFlow;
            current = dad;
        }
    }
    return flowFound;
}

class Solution{

public:
    void Senat();
    void Harta();
};

///SCRIE DESCRIEREA PROBLEMEI SI A IDEI
void Solution::Senat(){
    ifstream f("senat.in");
    ofstream g("senat.out");

    int n,m;
    f>>n>>m;

    vector<vector<int>> adjacency(n+m+2);
    vector<vector<int>> capacity(n+m+2, vector<int>(n+m+2, 0));

    string line;
    getline(f,line);

    ///connections between the 2 disjoint sets
    for(int i = 1 ; i <= m ; i++){
        getline(f,line);

        int nr = 0;
        for(int j = 0 ; j < line.size() ; j++){
            if(line[j] != ' ')
                nr = nr*10 + (line[j] - '0');
            else{
                adjacency[nr].push_back(n+i);
                adjacency[n+i].push_back(nr);
                capacity[nr][n+i] = 1;
                nr = 0;
            }
        }
        if(nr){
            adjacency[nr].push_back(n+i);
            adjacency[n+i].push_back(nr);
            capacity[nr][n+i] = 1;
        }
    }

    ///connect start to the first set
    for(int i = 1 ; i <= n ; i++){
        adjacency[0].push_back(i);
        adjacency[i].push_back(0);
        capacity[0][i] = 1;
    }

    ///connect second set to target
    for(int i = n + 1 ; i <= n + m ; i++){
        adjacency[i].push_back(n+m+1);
        adjacency[n+m+1].push_back(i);
        capacity[i][n+m+1] = 1;
    }


    MaxFlowGraph graph(adjacency,capacity);

    int flow = graph.maxFlow(0,n+m+1);

    if(flow != m)
        g<<0;

    else{
        for(int i = n+1 ; i <= n+m ; i++){
            for(int j = 1 ; j <= n + 1 ; j++)
                if(graph.getFlow()[j][i])
                    g<<j<<'\n';
        }
    }

    graph.printFlow();

    f.close();
    g.close();

}


void Solution::Harta(){
    ifstream f("harta.in");
    ofstream g("harta.out");

    int n;
    f>>n;

    vector<vector<int>>adjacency(n+n+2);
    vector<vector<int>>capacity(n+n+2,vector<int>(n+n+2, 0));

    for(int i = 1 ; i <= n ; i++ ){
        int x,y;
        f>>x>>y;

        ///from start to first set
        adjacency[0].push_back(i);
        adjacency[i].push_back(0);
        capacity[0][i] = x;

        ///from second set to target
        adjacency[n+i].push_back(n+n+1);
        adjacency[n+n+1].push_back(n+i);
        capacity[n+i][n+n+1] = y;
    }

    ///connect the middle
    for(int i = 1; i <= n ; i++)
        for(int j = 1 ; j <= n ; j++)
            if(i != j){
                adjacency[i].push_back(j + n);
                adjacency[j+n].push_back(i);
                capacity[i][j+n] = 1;
            }

    MaxFlowGraph graph(adjacency,capacity);

    int maxflow = graph.maxFlow(0,n+n+1);

    graph.printFlow();
    g<<maxflow<<endl;

    for(int i = 1 ; i <= n ; i++)
        for(int j = n + 1 ; j <= n+n ; j++)
            if(graph.getFlow()[i][j])
                g<<i<<" "<<j-n<<endl;



    f.close();
    g.close();
}
int main(){
    Solution sol;
    sol.Harta();

    return 0;
}