Cod sursa(job #2806153)

Utilizator DananauStefanRazvanDananau Stefan-Razvan DananauStefanRazvan Data 22 noiembrie 2021 13:37:37
Problema Diametrul unui arbore Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 11.91 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <utility>
#include <set>
#include <algorithm>
#include <bits/stdc++.h>

using namespace std;

#define INF 0x3f3f3f3f

class Graph {
    private:
        int n;
        int m;
        int start;
        int c;
        int last;
        int diam;
        static int noBC;
        vector<vector<int>> adjList;
        vector<vector<int>> adjListT;
        vector<int> dist;
        queue<int> q;
        bool vis[100001] = {false};
        bool visT[100001] = {false};
        vector<int> solComp[100001];
        stack<int> S;
        vector<int> lvl;
        vector<int> low;
        vector<vector<int>> solBC;
        vector<int> subset;
    public:
        Graph() {};
        void directedGraph();
        void undirectedGraph();
        void undirectedGraphBC();
        void directedGraphTopSort();
        void directedGraphCTC();
        void bfs();
        void dfs(int start);
        void noConnComp();
        void dfsBC(int start, int pred);
        int getSolBC();
        void dfsTopSort(int start, stack<int>& topSorted);
        void topSort();
        void dfsT(int start);
        void printCTC();
        void dijkstra();
        void bellmanford();
        struct edge {
            int a, b;
            int w;
            friend bool operator<(const edge& A, const edge& B) {
                return A.w < B.w;
            }
        };
        int findNode(int node);
        void unite(int node1, int node2);
        void apm();
        void disjoint();
        void royFloyd();
        void readDarb();
        void bfsDarb(int node);
        void solDarb();
};

int Graph :: noBC = 0;

void Graph :: directedGraph() {
    ifstream fin("bfs.in");

    fin >> n >> m >> start;

    adjList.resize(n + 1);

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

    fin.close();
}

void Graph :: undirectedGraph() {
    ifstream fin("dfs.in");

    fin >> n >> m;

    adjList.resize(n + 1);

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

    fin.close();
}

void Graph :: undirectedGraphBC() {
    ifstream fin("biconex.in");

    fin >> n >> m;

    adjList.resize(n + 1);
    solBC.resize(n + 1);
    lvl.resize(n + 1);
    low.resize(n + 1);

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

    fin.close();
}

void Graph :: directedGraphTopSort() {
    ifstream fin("sortaret.in");

    fin >> n >> m;

    adjList.resize(n + 1);

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

    fin.close();
}

void Graph :: directedGraphCTC() {
    ifstream fin("ctc.in");

    fin >> n >> m;

    adjList.resize(n + 1);
    adjListT.resize(n + 1);

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

    fin.close();
}

void Graph :: bfs() {
    ofstream fout("bfs.out");

    q.push(start);

    dist.resize(n + 1);
    for (int i = 1; i <= n; i++)
        dist[i] = -1;
    dist[start] = 0;

    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        for (auto i : adjList[nod])
            if (dist[i] == -1) {
                dist[i] = dist[nod] + 1;
                q.push(i);
            }
    }

    for (int i = 1; i <= n; i++)
        fout << dist[i] << " ";

    fout.close();
}

void Graph :: dfs(int start) {
    vis[start] = true;

    for (auto x : adjList[start])
        if (!vis[x])
            dfs(x);
}

void Graph :: noConnComp() {
    ofstream fout("dfs.out");

    int c = 0;

    for (int i = 1; i <= n; i++)
        if (!vis[i]) {
            dfs(i);
            c++;
        }

    fout << c;

    fout.close();
}

void Graph :: dfsBC(int start, int pred) {
    vis[start] = 1;
    S.push(start);
    lvl[start] = low[start] = lvl[pred] + 1;

    for (auto x : adjList[start])
        if (x != pred)
            if (vis[x])
                if (low[start] > lvl[x])
                    low[start] = lvl[x];
            else {
                dfsBC(x, start);

                if (low[start] > low[x])
                    low[start] = low[x];

                if (lvl[start] < low[x]) {
                    noBC++;

                    while (S.top() != x) {
                        solBC[noBC].push_back(S.top());
                        S.pop();
                    }

                    solBC[noBC].push_back(x);
                    S.pop();
                    solBC[noBC].push_back(start);
                }
            }

}

int Graph :: getSolBC() {
    return noBC;
}

void Graph :: dfsTopSort(int start, stack<int>& topSorted) {
    vis[start] = true;

    for (auto x : adjList[start])
        if (!vis[x])
            dfsTopSort(x, topSorted);

    topSorted.push(start);
}

void Graph :: topSort() {
    ofstream fout("sortaret.out");

    stack<int> topSorted;

    for (int i = 1; i <= n; i++)
        if (!vis[i])
            dfsTopSort(i, topSorted);

    while (!topSorted.empty()){
        fout << topSorted.top() << " ";
        topSorted.pop();
    }

    fout.close();
}

void Graph :: dfsT(int start) {
    visT[start] = true;

    solComp[c].push_back(start);

    for (auto x : adjList[start])
        if (!visT[x])
            dfsT(x);
}

void Graph :: printCTC() {
    ofstream fout("ctc.out");

    stack<int> topSorted;

    for (int i = 1; i <= n; i++)
        if (!vis[i])
            dfsTopSort(i, topSorted);

    while (!topSorted.empty()) {
        if (!visT[topSorted.top()]) {
            c++;
            dfsT(topSorted.top());
        }
        topSorted.pop();
    }

    cout << c << '\n';

    for (int i = 0; i < c; i++) {
        for (int j = 0; j < solComp[i].size(); j++)
            cout << solComp[i][j] << " ";
        cout << '\n';
    }

    fout.close();
}

void Graph :: dijkstra() {
    ifstream fin("dijkstra.in");
    ofstream fout("dijkstra.out");

    vector<vector<pair<int, int>>> adjList;
    priority_queue <pair<int, int>> q;
    int n, m;

    fin >> n >> m;

    adjList.resize(n + 1);

    for (int i = 0; i < m; i++) {
        int a, b, w;
        fin >> a >> b >> w;
        adjList[a].push_back(make_pair(b, w));
    }

    vector<int> dist(n + 1, INF);

    dist[1] = 0;
    q.push(make_pair(0, 1));

    while (!q.empty()) {
        int node = q.top().second;

        if (dist[node] != -q.top().first) {
            q.pop();
            continue;
        }

        q.pop();

        for (auto x : adjList[node])
            if (dist[node] + x.second < dist[x.first]) {
                dist[x.first] = dist[node] + x.second;
                q.push(make_pair(-dist[x.first], x.first));
            }
    }

    for (int i = 2; i <= n; i++)
        if (dist[i] != INF)
            fout << dist[i] << " ";
        else
            fout << 0 << " ";
}

void Graph :: bellmanford() {
    ifstream fin("bellmanford.in");
    ofstream fout("bellmanford.out");

    int n, m;
    vector<vector<pair<int, int>>> adjList;

    fin >> n >> m;

    adjList.resize(n + 1);

    for (int i = 0; i < m; i++) {
        int a, b, w;
        fin >> a >> b >> w;
        adjList[a].push_back(make_pair(b, w));
    }

    vector<int> dist(n + 1, INF);
    queue<int> q;
    vector<bool> vis;
    vector<int> used;

    vis.resize(n + 1);

    used.resize(n + 1);

    dist[1] = 0;
    q.push(1);

    bool finish = false;

    while (!q.empty()) {
        if (finish)
            break;

        int x = q.front();
        q.pop();
        vis[x] = false;

        for (auto i : adjList[x])
            if (dist[i.first] > dist[x] + i.second) {
                ++used[i.first];

                if (used[i.first]  == n) {
                    fout << "Ciclu negativ!";
                    finish = true;
                    break;
                }

                dist[i.first] = dist[x] + i.second;

                if (vis[i.first] == false) {
                    q.push(i.first);
                    vis[i.first] = true;
                }
            }
    }

    if (!finish)
        for (int i = 2; i <= n; i++)
            fout << dist[i] << " ";
}

int Graph :: findNode(int node) {
    if (node == subset[node])
        return node;
    return subset[node] = findNode(subset[node]);
};

void Graph :: unite(int node1, int node2) {
    int a = findNode(node1);
    int b = findNode(node2);
    subset[b] = a;
}

void Graph :: apm() {
    ifstream fin("apm.in");
    ofstream fout("apm.out");

    int n, m;
    vector<edge> adjList;
    vector<pair<int, int>> sol;

    fin >> n >> m;

    subset.resize(n + 1);

    for (int i = 1; i <= n; i++)
        subset[i] = i;

    for (int i = 1; i <= m; i++) {
        edge X;
        fin >> X.a >> X.b >> X.w;
        adjList.push_back(X);
    }

    sort(adjList.begin(), adjList.end());

    int s = 0;

    for (auto i : adjList) {
        int a = findNode(i.a);
        int b = findNode(i.b);

        if (a == b)
            continue;
        else {
            unite(i.a, i.b);
            sol.emplace_back(i.a, i.b);
            s += i.w;
        }
    }

    fout << s << '\n' << n - 1 << '\n';
    for (auto i : sol)
        fout << i.first << " " << i.second << '\n';

}

void Graph :: disjoint() {
    ifstream fin("disjoint.in");
    ofstream fout("disjoint.out");

    int n, m;

    fin >> n >> m;

    subset.resize(n + 1);

    for (int i = 1; i <= n; i++)
        subset[i] = i;

    while (m) {
        int c, x, y;

        fin >> c >> x >> y;

        if (c == 1)
            unite(x, y);
        else
            if (findNode(x) == findNode(y))
                fout << "DA\n";
            else
                fout << "NU\n";
        m--;
    }
}

void Graph :: royFloyd() {
    ifstream fin("royfloyd.in");
    ofstream fout("royfloyd.out");

    int n;

    fin >> n;

    adjList.resize(n + 1, vector<int> (n + 1, 0));

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
            fin >> adjList[i][j];
            if (adjList[i][j] == 0 && i != j)
                adjList[i][j] = INF;
        }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            for (int k = 0; k < n; k++)
                if (adjList[j][i] + adjList[i][k] < adjList[j][k])
                    adjList[j][k] = adjList[j][i] + adjList[i][k];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++)
            fout << adjList[i][j] << " ";
        fout << '\n';
    }
}

void Graph :: readDarb() {
    ifstream fin("darb.in");

    int n;

    fin >> n;

    adjList.resize(n + 1, vector<int> (n + 1, 0));

    for (int i = 0; i < n - 1; i++) {
        int a, b;
        fin >> a >> b;
        adjList[a].push_back(b);
        adjList[b].push_back(a);
    }
}

void Graph :: bfsDarb(int node) {
    dist.resize(100001, 0);

    q.push(node);
    dist[node] = 1;
    int maxim = node;

    while (!q.empty()) {
        int x = q.front();
        last = x;
        for (auto y : adjList[x]) {
            if (!dist[y]) {
                dist[y] = dist[x] + 1;
                q.push(y);
            }
        }
        q.pop();
    }
}

void Graph :: solDarb() {
    ofstream fout("darb.out");
    bfsDarb(1);
    dist.clear();
    bfsDarb(last);
    fout << dist[last];
}
int main()
{
    Graph X;
    X.readDarb();
    X.solDarb();
    return 0;
}