Cod sursa(job #2969307)

Utilizator StanCatalinStanCatalin StanCatalin Data 22 ianuarie 2023 20:51:35
Problema Arbore partial de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.69 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

ifstream in("apm.in");
ofstream out("apm.out");

const int dim = 2e5 + 5;

int n,m, viz[dim], distante[dim], s, in_deg[dim], nivel[dim], niv_min[dim];
vector<int> vec_nocost[dim];
vector<int> vec_nocost_transpus[dim];
vector<int> vizitate_acum;

stack<int> st;

void Citeste_nocost() {
    in >> n >> m;
//    in >> s;
    for (int i=0, x, y; i<m; i++) {
        in >> x >> y;
        in_deg[y]++;
        vec_nocost[x].push_back(y);
        vec_nocost[y].push_back(x);

//        vec_nocost_transpus[y].push_back(x);
    }
}

void DFS(int nod) {
    viz[nod] = 1;
    for (auto y:vec_nocost[nod]) {
        if (!viz[y]) {
            DFS(y);
        }
    }
    st.push(nod);
}

void DFS_transpus(int nod) {
    viz[nod] = 1;
    vizitate_acum.push_back(nod);
    for (auto y:vec_nocost_transpus[nod]) {
        if (!viz[y]) {
            DFS_transpus(y);
        }
    }
}

void BFS(int start) {
    for (int i=1; i<=n; i++) {
        distante[i] = -1;
    }
    distante[start] = 0;
    queue<int> q;
    q.push(start);
    viz[start] = 1;
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        for (auto y:vec_nocost[nod]) {
            if (!viz[y]) {
                viz[y] = 1;
                distante[y] = distante[nod] + 1;
                q.push(y);
            }
        }
    }

    for (int i=1; i<=n; i++) {
        out << distante[i] << " ";
    }
}

int Nr_CompConexe() {
    int cnt = 0;
    for (int i=1; i<=n; i++) {
        if (!viz[i]) {
            cnt++;
            DFS(i);
        }
    }
    return cnt;
}


vector<int> SortareTopologicaBFS() {
    queue<int> q;
    vector<int> rasp;
    for (int i=1; i<=n; i++) {
        if (in_deg[i] == 0) {
            q.push(i);
        }
    }

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

        for (auto y:vec_nocost[nod]) {
            in_deg[y]--;
            if (in_deg[y] == 0) {
                q.push(y);
            }
        }
    }
    return rasp;
}

void AfisVector(vector<int> &vec) {
    for (auto y:vec) {
        out << y << " ";
    }
}

void ComponenteTareConexe() {
    for (int i=1; i<=n; i++) {
        if (!viz[i]) {
            DFS(i);
        }
    }
    for (int i=1; i<=n; i++) {
        viz[i] = 0;
    }
    vector<vector<int>> vec;
    while (!st.empty()) {
        int nod = st.top();

        st.pop();
        if (!viz[nod]) {
            vizitate_acum.clear();
            DFS_transpus(nod);
            vec.push_back(vizitate_acum);
        }
    }

    out << vec.size() << "\n";
    for (int i=0; i<vec.size(); i++) {
        for (auto y:vec[i]) {
            out << y << " ";
        }
        out << "\n";
    }
}

stack<pair<int,int>> st_biconex;
vector<vector<int>> rasp;

void DFS_NIVMIN_NIV(int nod) {

    niv_min[nod] = nivel[nod];
    viz[nod] = 1;
    for (auto y:vec_nocost[nod]) {
        if (!viz[y]) { // muchie de avansare
            st_biconex.push({nod, y});
            nivel[y] = 1 + nivel[nod];
            DFS_NIVMIN_NIV(y);

            niv_min[nod] = min(niv_min[nod], niv_min[y]);


            if (niv_min[y] > nivel[nod]) { /// muchie critica si nod e punct critic

            }

            if (niv_min[y] == niv_min[nod]) { /// nod e punct critic

            }

            if (niv_min[y] >= nivel[nod]) { /// nod e punct critic
                int a, b;
                vector<int> aux;
                do {
                    a = st_biconex.top().first;
                    b = st_biconex.top().second;
                    aux.push_back(a);
                    aux.push_back(b);
                    st_biconex.pop();
                } while (a != nod || b != y);

                rasp.push_back(aux);
            }


            if (niv_min[y] < nivel[nod]) { /// e pe un ciclu

            }

        } else {
            if (nivel[y] < nivel[nod] - 1) { /// muchie de intoarcere
                niv_min[nod] = min(niv_min[nod], nivel[y]);
            }
        }
    }
}

//
//void DFS(int nod, vector<vector<int>> &critice) {
//    viz[nod] = 1;
//    niv_min[nod] = nivel[nod];
//    for (auto y:vec[nod]) {
//        if (!viz[y]) {
//            nivel[y] = 1 + nivel[nod];
//            DFS(y, critice);
//            niv_min[nod] = min(niv_min[nod], niv_min[y]);
//
//            if (niv_min[y] > nivel[nod]) {
//                vector<int> a;
//                a.push_back(nod);
//                a.push_back(y);
//                critice.push_back(a);
//            }
//        } else {
//            if (nivel[y] < nivel[nod] - 1) {
//                niv_min[nod] = min(nivel[y], niv_min[nod]);
//            }
//        }
//    }
//}

void ComponenteBiconexe(int nod) {
    DFS_NIVMIN_NIV(1);
}

int parent[dim], rang[dim];

int Find(int u) {
    while (parent[u] != 0) {
        u = parent[u];
    }
    return u;
}

void Union(int u, int v) {
    int ru, rv;
    ru = Find(u);
    rv = Find(v);

    if (rang[ru] < rang[rv]) {
        parent[ru] = rv;
    } else {
        parent[rv] = ru;
        if (rang[ru] == rang[rv]) {
            rang[rv]++;
        }
    }
}

int Kruskal() {
    vector<pair<int,pair<int,int>>> muchii;
    vector<pair<int,int>> alese;
    int cost_total = 0;
    int x, y, c;
    in >> n >> m;
    while (m--) {
        in >> x >> y >> c;
        muchii.push_back({c, {x, y}});
    }
    sort(muchii.begin(), muchii.end());
    for (int i=0; i<muchii.size(); i++) {
        c = muchii[i].first;
        x = muchii[i].second.first;
        y = muchii[i].second.second;

        if (Find(x) != Find(y)) {
            cost_total += c;
            alese.push_back({x, y});
            Union(x, y);
        }
    }
    out << cost_total << "\n";
    out << alese.size() << "\n";
    for (auto y:alese) {
        out << y.first << " " << y.second << "\n";
    }
    return cost_total;
}

int Prim() {

}

int main() {
 //   Citeste_nocost();
/*    vector<int> rasp = SortareTopologicaBFS();
    AfisVector(rasp);*/


//    /// sortare topologica cu DFS
//    for (int i=1; i<=n; i++) {
//        if (!viz[i] && in_deg[i] == 0) {
//            DFS(i);
//        }
//    }
//    while (!st.empty()) {
//        out << st.top() << " ";
//        st.pop();
//    }

//    ComponenteTareConexe();

// biconexe
//    ComponenteBiconexe(1);
//    out << rasp.size() << "\n";
//    for (int i=0; i<rasp.size(); i++) {
//        sort(rasp[i].begin(), rasp[i].end());
//        for (int j=0; j<rasp[i].size(); j++) {
//            int x = rasp[i][j];
//            out << x << " ";
//            while (j < rasp[i].size() && rasp[i][j] == x) {
//                j++;
//            }
//            j--;
//        }
//        out << "\n";
//    }
Kruskal();
    return 0;
}