Cod sursa(job #2969496)

Utilizator StanCatalinStanCatalin StanCatalin Data 23 ianuarie 2023 11:45:19
Problema Floyd-Warshall/Roy-Floyd Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 9.81 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

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

const int dim = 50005;

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;
vector<pair<int,int>> vec[dim];

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) {
    if (u == parent[u]) {
        return u;
    }
    parent[u] = Find(parent[u]);
    return parent[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;
    for (int i=1; i<=n; i++) {
        parent[i] = i;
    }
    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 nod) {
    int cost[dim];
    int dist[dim];
    in >> n >> m;
    for (int i=1; i<=n; i++) {
        parent[i] = 0;
        dist[i] = 1e9;
    }
    int x, y, c;
    while (m--) {
        in >> x >> y >> c;
        vec[x].push_back({y, c});
        vec[y].push_back({x, c});
    }

    dist[nod] = 0;
    priority_queue <pair <int,int>, vector<pair <int,int> >, greater<pair <int,int>>> pq;

    pq.push({0, nod});
    int total_cost = 0;
    while (!pq.empty()) {
        pair <int,int> acum = pq.top();
        pq.pop();
        viz[acum.second]++;
        if (viz[acum.second] == 1)
        {
            for (auto v : vec[acum.second])
            {
                if (viz[v.first] == 0) {

                    if (dist[v.first] > v.second) {
                        dist[v.first] = v.second;
                        parent[v.first] = acum.second;
                        pq.push({dist[v.first], v.first});
                        cost[v.first] = v.second;
                    }
                }
            }
            viz[acum.second] = 1;
        }
    }

    for (int i=1; i<=n; i++) {
        if (i != nod) {
            total_cost += cost[i];
        }
    }
    out << total_cost << "\n" << n - 1 << "\n";
    for (int i=1; i<=n; i++) {
        if (i != nod) {
            out << i << " " << parent[i] << "\n";
        }
    }
    return total_cost;
}

void Dijkstra() {
    in >> n >> m;
    int x, y, z;
    while (m--) {
        in >> x >> y >> z;
        vec[x].push_back({z, y});
    }
    priority_queue <pair <int,int>, vector<pair <int,int> >, greater<pair <int,int>>> pq;
    int dist[dim], viz[dim];
    for (int i=1; i<=n; i++) {
        dist[i] = 1e9;
        viz[i] = 0;
    }
    dist[1] = 0;
    pq.push({0, 1});
    while (!pq.empty()) {
        auto aux = pq.top();
        pq.pop();
        int nod = aux.second;
        int cost = aux.first;
        if (!viz[nod]) {
            for (auto y: vec[nod]) {
                if (dist[y.second] > dist[nod] + y.first) {
                    dist[y.second] = dist[nod] + y.first;
                    pq.push({dist[y.second], y.second});
                }
            }
            viz[nod] = 1;
        }
    }

    for (int i=2; i<=n; i++) {
        if (dist[i] == 1e9) {
            dist[i] = 0;
        }
        out << dist[i] << " ";
    }

}

void RoyFloyd() {
    int n;
    int dp[105][105];
    in >> n;
    for (int i=1; i<=n; i++) {
        for (int j=1; j<=n; j++) {
            in >> dp[i][j];
            if (i != j && dp[i][j] == 0)
            {
                dp[i][j] = 1e9;
            }
        }
    }

    for (int k=1; k<=n; k++) {
        for (int i=1; i<=n; i++) {
            for (int j=1; j<=n; j++) {
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
            }
        }
    }

    for (int i=1; i<=n; i++) {
        for (int j=1; j<=n; j++) {
            if (i != j && dp[i][j] == 1e9)
            {
                dp[i][j] = 0;
            }
            out << dp[i][j] << " ";
        }
        out << "\n";
    }
}

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";
//    }
//    Prim(1);
    RoyFloyd();
    return 0;
}