Cod sursa(job #2814162)

Utilizator Theo_FurtunaTheodor-Florentin Furtuna Theo_Furtuna Data 7 decembrie 2021 17:45:29
Problema Diametrul unui arbore Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 23.29 kb
#include <fstream>
#include <iostream> 
#include <vector>
#include <queue> 
#include <algorithm> 
using namespace std;
ifstream in("darb.in");
ofstream out("darb.out");
class Graf
{
    int muchii;
    int noduri;
    int maxim;
    vector<int> okey;
    vector<int> adiacenta[1000];
    vector<int> pozitii[1000];
    vector<vector<int>> lista;
public:
    //DFS
    void citire_DFS()
    {
        int x, y;
        in >> noduri >> muchii;
        lista.resize(noduri + 1);
        for (int i = 1; i <= muchii; i++)
        {
            in >> x >> y;
            lista[x].push_back(y);
            lista[y].push_back(x);
        }
    }
    void DFS(int q, vector <int>& vizitat)
    {
        vizitat[q] = 1;
        for (int i = 0; i < lista[q].size(); i++)
            if (!vizitat[lista[q][i]])
                DFS(lista[q][i], vizitat);
    }
    void afisare_DFS()
    {
        vector <int> vizitat;
        int nr = 0;
        for (int i = 0; i <= noduri; i++)
            vizitat.push_back(0);
        for (int i = 1; i <= noduri; i++)
            if (!vizitat[i])
            {
                nr++;
                DFS(i, vizitat);
            }
        out << nr;
    }
    //BFS
    void BFS()
    {
        int x, y, start;
        vector<int> distanta, coada;
        cin >> noduri >> muchii >> start;
        coada.resize(noduri + 1);
        for (int i = 0; i <= noduri; i++)
            coada[i] = 0;
        distanta.resize(noduri + 1);
        for (int i = 0; i <= noduri; i++)
            distanta[i] = 0;
        lista.resize(noduri + 1);
        for (int i = 1; i <= muchii; i++)
        {
            cin >> x >> y;
            lista[x].push_back(y);
        }
        distanta.resize(noduri + 1);
        for (int i = 1; i <= noduri; i++)
            distanta[i] = -1;
        x = y = 1;
        distanta[start] = 0;
        coada[x] = start;
        while (x <= y)
        {
            for (int i = 0; i < lista[coada[x]].size(); i++)
                if (distanta[lista[coada[x]][i]] == -1)
                {
                    y++;
                    coada[y] = lista[coada[x]][i];
                    distanta[lista[coada[x]][i]] = distanta[coada[x]] + 1;
                }
            x++;
        }
        for (int i = 1; i <= noduri; i++)
            cout << distanta[i] << " ";
    }
    //Havel Hakimi
    void HH()
    {
        vector<int> vector = { 3, 3, 3, 3 };
        int iesire = 0;
        while (!iesire)
        {
            sort(vector.begin(), vector.end(), greater<>());
            if (vector[0] == 0)
            {
                iesire++;
                break;
            }
            int v = vector[0];
            vector.erase(vector.begin() + 0);
            if (v > vector.size())
            {
                iesire = 0;
                break;
            }
            for (int i = 0; i < v; i++)
            {
                vector[i]--;
                if (vector[i] < 0)
                {
                    iesire = 0;
                    break;
                }
            }
        }
        if (iesire)
            cout << "Da";
        else
            cout << "Nu";
    }
    //Componente Tare Conexe
    void CTC()
    {
        int  x, y, nr_ctc = 0;
        vector <int> vizitat;
        cin >> noduri >> muchii;
        vizitat.resize(noduri + 1);
        for (int i = 0; i <= noduri; i++)
            vizitat.push_back(0);
        for (int i = 0; i <= muchii; i++)
            adiacenta[i].resize(noduri + 1);
        for (int i = 0; i < muchii; i++)
        {
            cin >> x >> y;
            adiacenta[x][y] = 1;
        }
        for (int i = 1; i <= noduri; i++)
            for (int j = 1; j <= noduri; j++)
                for (int k = 1; k <= noduri; k++)
                    if (i != j && i != k && j != k)
                        if (adiacenta[j][i] && adiacenta[i][k])
                            adiacenta[j][k] = 1;
        for (int i = 1; i <= noduri; i++)
        {
            if (!vizitat[i])
            {
                nr_ctc++;
                vizitat[i] = nr_ctc;
                for (int j = 1; j <= noduri; j++)
                    if (adiacenta[i][j] && adiacenta[j][i])
                        vizitat[j] = nr_ctc;
            }
        }
        cout << nr_ctc << "\n";
        for (int i = 1; i <= nr_ctc; i++)
        {
            for (int j = 1; j <= noduri; j++)
                if (vizitat[j] == i)
                    cout << j << " ";
            cout << "\n";
        }
    }
    //Sortare Topologica
    void DFS_2(int q, vector <int>& vizitat, vector <int>& afisare)
    {
        vizitat[q] = 1;
        for (int i = 0; i < lista[q].size(); i++)
            if (!vizitat[lista[q][i]])
                DFS_2(lista[q][i], vizitat, afisare);
        afisare.push_back(q);
    }
    void ST()
    {
        vector <int> vizitat, afisare;
        for (int i = 0; i <= noduri; i++)
            vizitat.push_back(0);
        for (int i = 1; i <= noduri; i++)
            if (!vizitat[i])
            {
                DFS_2(i, vizitat, afisare);
            }
        for (int i = afisare.size() - 1; i >= 0; i--)
            cout << afisare[i] << " ";
    }
    //Conexiune Critica
    void DFS_3(int timp, vector<vector<int>>& v, vector<int>& numarare, int k, int parinte, vector<bool>& vizite, vector<int>& vecin)
    {
        vizite[k] = 1;
        numarare[k] = timp++;
        vecin[k] = numarare[k];
        for (auto fiu : v[k])
        {
            if (fiu == parinte)
                continue;
            if (!vizite[fiu])
            {
                DFS_3(timp, v, numarare, fiu, k, vizite, vecin);
                vecin[k] = min(vecin[k], vecin[fiu]);
                if (vecin[fiu] > numarare[k])
                    lista.push_back({ k, fiu });
            }
            else
                vecin[k] = min(vecin[k], numarare[fiu]);
        }
        return;
    }
    vector<vector<int>> criticalConnections(int n, vector<vector<int>>& connections)
    {
        int timp = 0;
        vector<vector<int>> v(n);
        vector<int> numarare(n, 0);
        vector<int> vecin(n, 0);
        vector<bool> vizite(n, 0);
        for (int i = 0; i < connections.size(); i++)
        {
            v[connections[i][0]].push_back(connections[i][1]);
            v[connections[i][1]].push_back(connections[i][0]);
        }
        DFS_3(timp, v, numarare, 0, -1, vizite, vecin);
        return lista;
    }
    //Arbore Partial de Cost Minim
    void APM()
    {
        vector<int> x, y, z, v, capat1, capat2;
        in >> noduri >> muchii;
        x.resize(muchii + 1);
        y.resize(muchii + 1);
        z.resize(muchii + 1);
        v.resize(muchii + 1);
        capat1.resize(muchii + 1);
        capat2.resize(muchii + 1);
        for (int i = 0; i <= muchii; i++)
        {
            x.push_back(0);
            y.push_back(0);
            z.push_back(0);
            v.push_back(0);
            capat1.push_back(0);
            capat2.push_back(0);
        }
        for (int i = 1; i <= muchii; i++)
            in >> x[i] >> y[i] >> z[i];
        for (int i = 1; i <= noduri; i++)
            v[i] = i;
        for (int i = 1; i < muchii; i++)
            for (int j = i + 1; j <= muchii; j++)
            {
                if (z[i] > z[j])
                {
                    swap(x[i], x[j]);
                    swap(y[i], y[j]);
                    swap(z[i], z[j]);
                }
            }
        int k = 0, nr = 0, cost = 0, minn, maxx;
        while (nr < noduri - 1)
        {
            k++;
            if (v[x[k]] != v[y[k]])
            {
                nr++;
                cost += z[k];
                capat1[nr] = y[k];
                capat2[nr] = x[k];
                if (v[x[k]] > v[y[k]])
                {
                    minn = v[y[k]];
                    maxx = v[x[k]];
                }
                else
                {
                    minn = v[x[k]];
                    maxx = v[y[k]];
                }
                for (int i = 1; i <= noduri; i++)
                    if (v[i] == maxx)
                        v[i] = minn;
                for (int i = 1; i <= noduri; i++)
                    if (v[i] == v[minn])
                        v[i] = v[maxx];
            }
        }
        out << cost << "\n" << noduri - 1 << "\n";
        for (int i = 1; i < noduri; i++)
            out << capat1[i] << " " << capat2[i] << "\n";
    }
    //Dijkstra
    void Djk()
    {
        int  x, y, cost, nr_noduri, p, q;
        vector <int> costuri[5000], drumuri, h, d, lungime;
        in >> noduri >> muchii;
        drumuri.resize(muchii + 1);
        h.resize(muchii + 1);
        d.resize(muchii + 1);
        lungime.resize(muchii + 1);
        for (int i = 0; i <= muchii; i++)
        {
            drumuri.push_back(0);
            h.push_back(0);
            d.push_back(0);
            lungime.push_back(0);
            adiacenta[i].resize(noduri + 1);
            costuri[i].resize(noduri + 1);
        }
        for (int i = 1; i <= muchii; i++)
        {
            in >> x >> y >> cost;
            adiacenta[x].push_back(y);
            costuri[x].push_back(cost);
            if (i <= noduri)
            {
                drumuri[i] = 100000;
                h[i] = i;
                d[i] = i;
            }
            lungime[x] = adiacenta[x].size();
        }
        drumuri[1] = 0;
        nr_noduri = noduri;
        for (int i = 1; i <= noduri; i++)
        {
            for (int j = 0; j < lungime[h[1]]; j++)
                if (drumuri[h[1]] + costuri[h[1]][j] < drumuri[adiacenta[h[1]][j]])
                {
                    drumuri[adiacenta[h[1]][j]] = drumuri[h[1]] + costuri[h[1]][j];
                    p = d[adiacenta[h[1]][j]];
                    q = 1;
                    while (q == 1 && p > 1)
                    {
                        q = 0;
                        if (drumuri[h[p]] < drumuri[h[p + 1]])
                        {
                            q = 1;
                            swap(h[p], h[p + 1]);
                            swap(d[h[p]], d[h[p + 1]]);
                            p++;
                        }
                    }
                }
            d[h[1]] = nr_noduri;
            h[1] = h[nr_noduri--];
            p = 1;
            while (1)
            {
                y = 0;
                if (nr_noduri >= p * 2 + 1 && drumuri[h[p * 2 + 1]] < drumuri[h[p * 2]])
                    y = 1;
                if (nr_noduri >= p * 2 + y && drumuri[h[p]] > drumuri[h[p * 2 + y]])
                {
                    q = 1;
                    swap(h[p], h[p * 2 + y]);
                    swap(d[h[p]], d[h[p * 2 + y]]);
                    p = p * 2 + y;
                    continue;
                }
                break;
            }
        }
        for (int i = 2; i <= noduri; i++)
        {
            if (drumuri[i] == 100000)
                out << "0 ";
            else
                out << drumuri[i] << " ";
        }
    }
    //Bellman-Ford
    void BF()
    {
        vector <int> costuri[1000], distanta, v;
        in >> noduri >> muchii;
        distanta.resize(noduri + 1);
        v.resize(noduri + 1);
        for (int i = 0; i <= muchii; i++)
        {
            v.push_back(0);
            adiacenta[i].resize(noduri + 1);
            costuri[i].resize(noduri + 1);
        }
        int x, y, z;
        for (int i = 1; i <= muchii; i++)
        {
            in >> x >> y >> z;
            adiacenta[x].push_back(y);
            costuri[x].push_back(z);
        }
        int final = 0, inceput = 0;
        for (int i = 1; i <= noduri; i++)
            distanta[i] = 10000;
        v[inceput] = 1;
        v[final] = 1;
        distanta[1] = 0;
        while (inceput <= final)
        {
            x = v[inceput];
            inceput++;
            for (int i = 0; i < adiacenta[x].size(); i++)
                if (distanta[adiacenta[x][i]] > distanta[x] + costuri[x][i])
                {
                    distanta[adiacenta[x][i]] = distanta[x] + costuri[x][i];
                    v[++final] = adiacenta[x][i];
                }
        }
        for (int i = 2; i <= noduri; i++)
            if (distanta[i] == 10000)
                out << 0;
            else
                out << distanta[i] << " ";

    }
    //Paduri de multimi disjuncte
    int get_root(int x, vector<int>multime)
    {
        while (multime[x] != x)
            x = multime[x];
        return x;
    }
    void Dis()
    {
        int nr_multimi, nr_operatii;
        vector<int> multime;
        in >> nr_multimi >> nr_operatii;
        multime.resize(nr_operatii + 1);
        for (int i = 0; i <= nr_operatii; i++)
            multime.push_back(0);
        for (int i = 1; i <= nr_multimi; i++)
            multime[i] = i;
        for (int i = 1; i <= nr_operatii; i++)
        {
            int cod, x, y, a, b;
            in >> cod >> x >> y;
            a = get_root(x, multime);
            b = get_root(y, multime);
            if (cod == 1)
            {
                if (a < b)
                    multime[b] = a;
                else
                    multime[a] = b;
            }
            else
            {
                if (a == b)
                    out << "DA\n";
                else
                    out << "NU\n";
            }
        }
    }
    //Floyd-Warshall
    void citire_FW()
    {
        in >> noduri;
        for (int i = 0; i <= noduri; i++)
            adiacenta[i].resize(noduri + 1);
        for (int i = 1; i <= noduri; i++)
            for (int j = 1; j <= noduri; j++)
                in >> adiacenta[i][j];
    }
    void FW()
    {
        for (int k = 1; k <= noduri; k++)
            for (int i = 1; i <= noduri; i++)
                for (int j = 1; j <= noduri; j++)
                    if ((i != j) && adiacenta[i][k] && adiacenta[k][j])
                        if ((adiacenta[i][j] > (adiacenta[i][k] + adiacenta[k][j])) || (!adiacenta[i][j]))
                            adiacenta[i][j] = adiacenta[i][k] + adiacenta[k][j];
    }
    void afisare_FW()
    {
        for (int i = 1; i <= noduri; i++)
        {
            for (int j = 1; j <= noduri; j++)
                out << adiacenta[i][j] << " ";
            out << "\n";
        }
    }
    //Diametrul unui arbore
    void citire_arbore()
    {
        in >> noduri;
        okey.resize(noduri + 1);
        for (int i = 1; i < noduri; i++)
            adiacenta[i].resize(noduri + 1);
        for (int i = 1; i < noduri; i++)
        {
            int x, y;
            in >> x >> y;
            adiacenta[x].push_back(y);
            adiacenta[y].push_back(x);
            okey.push_back(0);
        }
    }
    void DFS_arbore(int nod, int distanta)
    {
        if (distanta > maxim)
            maxim = distanta;
        okey[nod] = 1;
        for (int i = 0; i < adiacenta[nod].size(); i++)
            if (!okey[adiacenta[nod][i]])
                DFS_arbore(adiacenta[nod][i], distanta + 1);
        okey[nod] = 0;
    }
    void afisare_diametru()
    {
        for (int i = 0; i < noduri; i++)
            DFS_arbore(i, 0);
        out << maxim;
    }
    //Flux maxim
    void citire_flux()
    {
        in >> noduri >> muchii;
        for (int i = 1; i < muchii; i++)
            adiacenta[i].resize(noduri + 1);
        int x, y, cost;
        while (in >> x >> y >> cost)
            adiacenta[x][y] = cost;
    }
    int bfs_flux(vector<int> Fluxuri[1000], vector<int>& vizitat, vector<int>& coada, vector<int>& distanta)
    {
        int primul = 1, ultimul = 1;
        coada[primul] = 1;
        vizitat[1] = -1;
        distanta[1] = 100000;
        while (primul <= ultimul)
        {
            for (int i = 1; i <= noduri; i++)
                if (!vizitat[i] && adiacenta[coada[primul]][i] - Fluxuri[coada[primul]][i] > 0)
                {
                    vizitat[i] = coada[primul];
                    coada[++ultimul] = i;
                    if (distanta[coada[primul]] < adiacenta[coada[primul]][i] - Fluxuri[coada[primul]][i])
                        distanta[i] = distanta[coada[primul]];
                    else
                        distanta[i] = adiacenta[coada[primul]][i] - Fluxuri[coada[primul]][i];
                    if (i == noduri)
                        return 0;
                }
            primul++;
        }
    }
    void afisare_flux()
    {
        vector<int> Fluxuri[1000], vizitat(noduri + 1, 0), coada(noduri + 1, 0), distanta(noduri + 1, 0);
        for (int i = 1; i < muchii; i++)
            Fluxuri[i].resize(noduri + 1);
        for (int i = 1; i < muchii; i++)
            Fluxuri[i].push_back(0);
        int x, y, minim, flux = 0;
        do
        {
            for (int i = 1; i <= noduri; i++)
                distanta[i] = vizitat[i] = coada[i] = 0;
            bfs_flux(Fluxuri, vizitat, coada, distanta);
            if (vizitat[noduri])
            {
                minim = 100000;
                x = noduri;
                y = vizitat[x];
                minim = distanta[noduri];
                while (y != -1)
                {
                    Fluxuri[y][x] += minim;
                    Fluxuri[x][y] -= minim;
                    x = y;
                    y = vizitat[x];
                }
                flux += minim;
            }
        } while (vizitat[noduri]);
        out << flux;
    }
    //Ciclu Eulerian
    void citire_Euler()
    {
        in >> noduri >> muchii;
        okey.resize(noduri + 1);
        for (int i = 0; i <= muchii; i++)
        {
            adiacenta[i].resize(noduri + 1);
            pozitii[i].resize(noduri + 1);
        }
        for (int i = 0; i <= muchii; i++)
        {
            okey.push_back(0);
            adiacenta[i].push_back(0);
            pozitii[i].push_back(0);
        }
        for (int i = 1; i <= muchii; i++)
        {
            int x, y;
            in >> x >> y;
            adiacenta[x].push_back(y);
            adiacenta[y].push_back(x);
            pozitii[x].push_back(i);
            pozitii[y].push_back(i);
        }
    }
    void dfs_Euler(int x)
    {
        for (int i = 0; i < adiacenta[x].size(); i++)
            if (!okey[pozitii[x][i]])
            {
                okey[pozitii[x][i]] = 1;
                dfs_Euler(adiacenta[x][i]);
            }
        out << x << " ";
    }
    void afisare_Euler()
    {
        for (int i = 1; i <= noduri; i++)
            if (adiacenta[i].size() % 2 != 0)
            {
                out << "-1\n";
                break;
            }
        dfs_Euler(1);
    }
};
int main()
{
    Graf g;
    g.citire_arbore();
    g.afisare_diametru();
    //int nr_problema;
    //cout << "Lista cu probleme:\n";
    //cout << "1-DFS\n";
    //cout << "2-BFS\n";
    //cout << "3-Havel Hakimi\n";
    //cout << "4-Componente Tare Conexe\n";
    //cout << "5-Sortare Topologica\n";
    //cout << "6-Conexiune Critica\n";
    //cout << "7-Componente Biconexe\n";
    //cout << "8-Arbore Partial de Cost Minim\n";
    //cout << "9-Dijkstra\n";
    //cout << "10-Bellman-Ford\n";
    //cout << "11-Paduri de Multimi Disjuncte\n";
    //cout << "12-Floyd-Warshall\n";
    //cout << "13-Diametrul unui Arbore\n";
    //cout << "14-Flux Maxim\n";
    //cout << "15-Ciclu Eulerian\n";
    //cout << "Introduceti numarul problemei de rezolat:";
    //cin >> nr_problema;
    //if (nr_problema == 1)
    //{
    //    g.citire_DFS();
    //    g.afisare_DFS();
    //    /*
    //    6 3
    //    1 2
    //    1 4
    //    3 5
    //    */
    //}
    //else if (nr_problema == 2)
    //{
    //    g.BFS();
    //    /*
    //    5 7 2
    //    1 2
    //    2 1
    //    2 2
    //    3 2
    //    2 5
    //    5 3
    //    4 5
    //    */
    //}
    //else if (nr_problema == 3)
    //{
    //    g.HH();
    //}
    //else if (nr_problema == 4)
    //{
    //    g.CTC();
    //    /*
    //        8 12
    //        1 2
    //        2 6
    //        6 7
    //        7 6
    //        3 1
    //        3 4
    //        2 3
    //        4 5
    //        5 4
    //        6 5
    //        5 8
    //        8 7
    //        */
    //}
    //else if (nr_problema == 5)
    //{
    //    g.citire_DFS();
    //    g.ST();
    //    /*
    //        9 8
    //        1 2
    //        1 3
    //        3 4
    //        3 5
    //        5 9
    //        4 6
    //        4 7
    //        4 8
    //        */
    //}
    //else if (nr_problema == 6)
    //{
    //    //vector<vector<int>> aux;
    //    //aux = g.criticalConnections(4, { {0, 1} ,{1, 2},{2, 0},{1, 3} });
    //    cout << "Vizitati leetcode pentru a verifica aceasta problema";
    //}
    //else if (nr_problema == 7)
    //{
    //    cout << "Problema aceasta nu a fost adaugata inca";
    //}
    //else if (nr_problema == 8)
    //{
    //    /*
    //    9 14
    //    1 2 10
    //    1 3 -11
    //    2 4 11
    //    2 5 11
    //    5 6 13
    //    3 4 10
    //    4 6 12
    //    4 7 5
    //    3 7 4
    //    3 8 5
    //    8 7 5
    //    8 9 4
    //    9 7 3
    //    6 7 11
    //    */
    //    g.APM();
    //}
    //else if (nr_problema == 9)
    //{
    //    /*
    //    5 6
    //    1 2 1
    //    1 4 2
    //    4 3 4
    //    2 3 2
    //    4 5 3
    //    3 5 6
    //    */
    //    g.Djk();
    //}
    //else if (nr_problema == 10)
    //{
    //    /*
    //    5 8
    //    1 3 -3
    //    1 5 7
    //    3 2 -2
    //    3 4 7
    //    5 1 4
    //    5 2 3
    //    5 3 4
    //    4 5 3
    //    */
    //    g.BF();
    //}
    //else if (nr_problema == 11)
    //{
    //    /*
    //    4 6
    //    1 1 2
    //    1 3 4
    //    2 1 3
    //    2 1 2
    //    1 1 3
    //    2 1 4
    //    */
    //    g.Dis();
    //}
    //else if (nr_problema == 12)
    //{
    //    /*
    //    5
    //    0 3 9 8 3
    //    5 0 1 4 2
    //    6 6 0 4 5
    //    2 9 2 0 7
    //    7 9 3 2 0
    //    */
    //    g.citire_FW();
    //    g.FW();
    //    g.afisare_FW();
    //}
    //else if (nr_problema == 13)
    //{
    //    /*
    //    11
    //    1 2
    //    1 3
    //    1 4
    //    2 5
    //    3 6
    //    4 7
    //    5 8
    //    5 9
    //    6 10
    //    10 11
    //    */
    //    g.citire_arbore();
    //    g.afisare_diametru();
    //}
    //else if (nr_problema == 14)
    //{
    //    /*
    //    4 5
    //    1 2 3
    //    1 3 5
    //    2 4 6
    //    3 4 4
    //    3 2 3
    //    */
    //    g.citire_flux();
    //    g.afisare_flux();
    //}
    //else if (nr_problema == 15)
    //{
    //    /*
    //    4 6
    //    1 2
    //    1 3
    //    2 2
    //    2 3
    //    3 4
    //    3 4
    //    */
    //    g.citire_Euler();
    //    g.afisare_Euler();
    //}
    //cout << "\nProblema " << nr_problema << " a fost rezolvata, verificati in date.out ce s-a afisat\n";
    in.close();
    out.close();
    return 0;
}