Cod sursa(job #2905360)

Utilizator Costin_PintilieHoratiu-Costin-Petru Pintilie Costin_Pintilie Data 21 mai 2022 01:37:33
Problema Componente tare conexe Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 8.76 kb
#include <bits/stdc++.h>
using namespace std;

struct edge{
    int x,y;
    int curr_flow;
    int max_flow;
};

class Graph{
private:
        int n; //nr de noduri, nr de muchii, nodul de inceput
        int m; // nr de muchii
//        int s; // folosit la bfs, nodul de start
        bool type; //0 = neorientat; 1 = orientat
        bool capacity;
        bool flow;
        vector<vector <int>> adj; // adj = adjacent (=liste de vecini)
        vector < vector<int> > comp_nmbr; // folosit la biconexe, vector de vectori ce reprezinta componentele biconexe
        vector < vector<edge> > adj_flow;

public:
    Graph(string fname, bool type, bool flow);

    void BFS(int start);

    void DFS();

    void biconex();
    void DFS_biconex(int node, int low[], int disc[], int parent[], bool visited[], int time,stack <pair<int,int> >& st  );

    void TS(int node, bool visited[], stack<int>& sorted_nodes); //sortare topologica
    void TS_read();

    void APM();

    void MaxFlux();


};

Graph::Graph(string fname, bool type, bool flow){
    ifstream fin(fname);
    this->type = type;
    this->flow = flow;


//    if(this->type)
//    {
//        fin>>this->n>>this->m;
//        int x,y;
//        adj.resize(n+1);
//
//        for(int i = 0; i < m; i++)
//        {
//            fin>>x>>y;
//            adj[x].push_back(y);
//        }
//
//        fin.close();
//    }else{
//        fin>>this->n>>this->m;
//        int x,y;
//        adj.resize(n+1);
//
//        for(int i = 0; i < m; i++)
//        {
//            fin>>x>>y;
//            adj[x].push_back(y);
//            adj[y].push_back(x);
//        }
//    fin.close();
//    }

    switch(this->type){
case true:
        if(this->flow)
        {
                fin>>this->n>>this->m;
                int x,y,flow;
                edge e;
                for(int i = 0; i < m; i++)
                {
                    fin>>x>>y>>flow;
                    e.x = x;
                    e.y = y;
                    e.max_flow = flow;
                    e.curr_flow = 0;
                    adj_flow[e.x].push_back(e);
                }
                fin.close();
        }else{
            fin>>this->n>>this->m;
            int x,y;
            adj.resize(n+1);

            for(int i = 0; i < m; i++)
            {
                fin>>x>>y;
                adj[x].push_back(y);
            }

            fin.close();

            }
        break;

case false:
        fin>>this->n>>this->m;
        int x,y;
        adj.resize(n+1);

        for(int i = 0; i < m; i++)
        {
            fin>>x>>y;
            adj[x].push_back(y);
            adj[y].push_back(x);
        }
    fin.close();
    break;

    }
}

void Graph::APM(){
    ifstream fin("apm.in");
    fin>>n>>m;
    vector<pair<int,int>> apm_adj[20010];
    int x,y,c;

    for(int i = 0; i < m; i++){
        fin>>x>>y>>c;
        apm_adj[x].push_back(make_pair(y,c));
        apm_adj[y].push_back(make_pair(x,c));

    }
    fin.close();

//    for(int v = 1; v <= n; v++){
//        for(unsigned int j = 0; j< apm_adj[v].size(); j++ ){
//            cout<<v<<": "<<apm_adj[v][j].first<< " "<<apm_adj[v][j].second<<",\n";
//        }
//        cout<<"\n";
//    }

    priority_queue< pair<int,int>, vector< pair<int,int> >, greater< pair<int,int> > > pq;
    vector<bool> inAPM(n+1,false);
    vector<int> weight(n+1, 1100);
    vector<int> parent(n+1,-1);

    int start = 1;
    int s = 0;
    pq.push(make_pair(0,start));
    weight[start] = 0;
    while (!pq.empty()){

        int u = pq.top().second;

        pq.pop();
        if(inAPM[u] == true){
            continue;
        }
        inAPM[u] = true;


        for (auto x : apm_adj[u]){
            int v = x.first;
            int w = x.second;

            if(inAPM[v] == false && w < weight[v]){
                weight[v] = w;
                pq.push(make_pair(weight[v],v));
                parent[v] = u;
            }
        }
    }
    ofstream fout("apm.out");
    for(int i = 2; i <=n; i++){
        s+=weight[i];
    }
    fout<<s<<"\n"<<n-1<<"\n";

        for(int i = 2; i <=n; i++){
        fout<<parent[i] <<" "<<i<<"\n";
    }






}

void Graph::TS_read(){

    if (!this->type){
        cout<<("Topological sorting works only on oriented graphs!\n");
        exit(NULL);
    }

    stack<int> sorted_nodes;
    bool* visited = new bool[n+1];

    for(int i = 0; i <= n; i++){
        visited[i] = false;
    }

    for(int i = 1; i <= n; i++){
        if(!visited[i]){
            TS(i, visited, sorted_nodes);
        }

    }
    ofstream fout("sortaret.out");
    while(!sorted_nodes.empty()){
        fout<<sorted_nodes.top()<<" ";
        sorted_nodes.pop();
    }
    fout.close();
}

void Graph::TS(int node, bool visited[], stack<int>& sorted_nodes){
    visited[node] = true;

    for(auto it: adj[node]){
        if(!visited[it]){
            TS(it, visited, sorted_nodes);
        }

    }
    sorted_nodes.push(node);
}

void Graph::biconex(){

    if (this->type){
        cout<<("Biconex components exist only in unoriented graphs!\n");
        exit(NULL);
    }

    stack < pair<int,int> > st;
    int *disc = new int[n+1];
    int *low = new int[n+1];
    int *parent = new int[n+1];
    bool visited[n+1] = {0};
    int time = 0;

    for (int i = 1; i <= n; i++){
        disc[i] = -1;
        low[i] = -1;
        parent[i] = -1;
    }

    for (int i = 1; i <= n; i++){
        if (visited[i] == false){
            DFS_biconex(i, low, disc, parent, visited, time, st);
        }

    }
    ofstream fout("biconex.out");
    fout<<comp_nmbr.size()<<"\n";

    for(auto comp : comp_nmbr){
        for(auto node: comp){
            fout<<node<<" ";
        }
        fout<<"\n";
    }
    fout.close();

}

void Graph::DFS_biconex(int node, int low[], int disc[], int parent[], bool visited[], int time,stack <pair<int,int> >& st  ){
    disc[node] = time + 1; //timpul de descoperire in dfs
    low[node] = time + 1;
    time++;
    visited[node] = 1;
    int children = 0;

    for(int i: adj[node] ){

        if (visited[i] == false){
            children++;
            st.push({node,i});
            parent[i] = node;
            DFS_biconex(i, low, disc, parent, visited, time, st);
            low[node] = min(low[node], low[i]);

            if( (parent[node] == -1 && children > 1) || (disc[node] != -1 && low[i] >= disc[node] ) )
            {       /*^radacina                                ^restul nodurilor*/
                vector <int> components; // vector ajutator in care va fi stocata componenta biconexa curenta
                while(st.top().first != node && st.top().second != i){
                        components.push_back(st.top().second);
                        st.pop();
                }
                components.push_back(st.top().second);
                components.push_back(st.top().first);
                st.pop();
                comp_nmbr.push_back(components);

            }

        }else if (parent[node] != i && disc[i] < low[node]  ){
                    low[node] = disc[i];
                }
    }

}



void Graph::DFS(){
    bool visited[n+1] = {0};
    queue<int> q;
    int conex = 0;

    for(int i = 1; i < n+1; i++){
        if(!visited[i]){
            conex++;
            q.push(i);
            while( !q.empty() ){
                int curr_node = q.front();
                visited[curr_node] = 1;
                q.pop();
                for(unsigned int j = 0; j < adj[curr_node].size(); j++){
                    if(!visited[ adj[ curr_node][j] ] )
                        q.push(adj[curr_node][j] );
                }
            }
        }
    }
    ofstream fout("dfs.out");
    fout<<conex;
    fout.close();

}


void Graph::BFS(int start){
    bool visited[n+1];
    int length[n+1];

    for(int i = 0; i < n+1; i++){
        visited[i] = false;
        length[i] = -1;
    }

    visited[start] = true;
    length[start] = 0;

    queue<int> q;
    q.push(start);

    while(!q.empty()){
        int curr_node = q.front();
        q.pop();
        int nr_vec = adj[curr_node].size();

        for(int i = 0; i<nr_vec;i++){
            int x = adj[curr_node][i];

            if(!visited[x]){
                visited[x] = true;
                q.push(x);
                length[x] = length[curr_node] + 1;
            }
        }
    }

    ofstream fout("bfs.out");
    for(int i = 1; i <= n; i++){
        fout<<length[i]<<" ";
    }
    fout.close();
}

int main()
{
    int x = 2;
    Graph test("biconex.in",0,0);
    test.biconex();

    return 0;
}