Cod sursa(job #2807003)

Utilizator petru.burdusaBurdusa Petru petru.burdusa Data 23 noiembrie 2021 11:49:16
Problema Arbore partial de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 9.68 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

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

vector<int> listAux[100001];
vector<int> tareConexe[100001];
vector <int> v[50005],d[50005];
int nrTC=0;

struct edge{
    int cost,x,y;
};


bool cmp_edge(const edge &a,
              const edge &b)
{
    return (a.cost < b.cost);
}

bool cmp(const pair<int,int> &a,
         const pair<int,int> &b)
{
    return (a.second > b.second);
}



class Graf{
public:
    Graf(){}

    void bfs();
    void dfs();
    void sorttop();
    void havelHakimi();
    void ctc_Kosoraju();
    void dijkstra();
    void disjoint();
    void kruskal();

    int find(int x);
    void union_(int x, int y);
    void r_dfs(int q);
    void rr_dfs(int q);
    void sorttop_recursie(int q);


private:

    int m_nrMuchii;
    int m_nrNoduri;
    int m_start;
    int m_viz[100001];
    int m_q[100001];
    vector<int> m_ordtop;
    vector<int> m_grad;
    vector<int> m_stiva;
    set< pair<int,int> > s;
    vector<pair<int,int>> m_nodGrad;
    int m_aux;
    vector<int> m_list[100001];
    vector<int> m_parent, m_rank;

};



int main() {
    Graf graf;
    graf.kruskal();
}


void Graf::bfs()
{
    in>>m_nrNoduri>>m_nrMuchii>>m_start;
    for(int i=0;i<m_nrMuchii;i++)
    {
        int x,y;
        in>>x>>y;
        m_list[x].push_back(y);
    }

    for(int i=1;i<=m_nrNoduri;i++)
    {
        m_viz[i]=2000000000;
    }
    m_viz[m_start]=0;
    m_q[1]=m_start;
    int p=1;
    int u=1;
    while(p<=u) //<=
    {
        int r=m_q[p];
        for(int i=0;i<(m_list[r].size());i++)
        {
            int e=m_list[r][i];
            // cout<<e<<' ';

            if(m_viz[r]+1<m_viz[e])
            {
                m_viz[e]=m_viz[r]+1;
                u++;
                m_q[u]=e;


            }
        }
        p++;
    }
    for(int i=1;i<=m_nrNoduri;i++)
    {
        if(m_viz[i]!=2000000000)
            out<<m_viz[i]<<' ';
        else
            out<<"-1 ";
    }
}

void Graf::r_dfs(int q)
{
    m_viz[q]=1;
    for(int i=0;i<m_list[q].size();i++)
    {

        int r=m_list[q][i];

        if(m_viz[r]==0)
        {
            r_dfs(r);
        }


    }
    m_stiva.push_back(q);
}

void Graf::rr_dfs(int q)
{
    m_viz[q]=1;
    for(int i=0;i<m_list[q].size();i++)
    {

        int r=m_list[q][i];

        if(m_viz[r]==0)
        {
            rr_dfs(r);
        }


    }
    tareConexe[nrTC].push_back(q);
}

void Graf::dfs()
{
    in>>m_nrNoduri>>m_nrMuchii;
    for(int i=0;i<m_nrMuchii;i++)
    {
        int x,y;
        in>>x>>y;
        m_list[x].push_back(y);
        m_list[y].push_back(x);
    }

    int s=0;
    for(int i=1;i<=m_nrNoduri;i++)
    {
        if(m_viz[i]==0)
        {
            r_dfs(i);
            s++;
        }
    }
    r_dfs(1);
    out<<s<<'\n';
}

void Graf::sorttop_recursie(int q)
{
    int i;
    m_viz[q]=1;

    for(i=0;i<m_list[q].size();i++)
    {
        int t=m_list[q][i];
        if(m_viz[t]==0)
        {
            sorttop_recursie(t);

        }

    }
    m_aux++;
    m_ordtop[m_aux]=q;
}

void Graf::sorttop()
{
    int i;
    in>>m_nrNoduri>>m_nrMuchii;
    for(i=0;i<m_nrNoduri;i++)
    {
        m_grad.push_back(0);
        m_ordtop.push_back(0);
    }
    for(i=1;i<=m_nrMuchii;i++)
    {
        int x,y;
        in>>x>>y;
        m_list[x].push_back(y);
        m_grad[y]++;
    }
    for(i=1;i<=m_nrNoduri;i++)
    {
        if(m_grad[i]==0 && m_viz[i]==0)
        {
            sorttop_recursie(i);
        }
    }
    //cout<<w<<'\n';
    for(i=m_aux;i>0;i--)
    {
        out<<m_ordtop[i]<<' ';
    }
}

void Graf::havelHakimi()
{
    int s=0;
    in>>m_nrNoduri;
    for(int i=1;i<=m_nrNoduri;i++)
    {
        int x;
        in>>x;
        s+=x;
        m_nodGrad.push_back(make_pair(i,x));
        sort(m_nodGrad.begin(), m_nodGrad.end(),cmp);
    }

    if(s%2==0)
    {
        /*for(int i=0;i<m_nrNoduri;i++)
            cout<<m_nodGrad[i].second;
        cout<<'\n';
        for(int i=0;i<m_nrNoduri;i++)
            cout<<m_nodGrad[i].first;
        cout<<"\n\n";*/
        for(int i=1;i<=m_nrNoduri;i++)
        {
            if(m_nodGrad[i-1].second <= m_nrNoduri - i)
            {
                int aux = m_nodGrad[i-1].second;
                for(int j = 1; j <= aux; j++)
                {
                    m_nodGrad[i+j-1].second--;
                    m_nodGrad[i-1].second--;
                    m_list[m_nodGrad[i-1].first].push_back(m_nodGrad[i+j-1].first);
                    m_list[m_nodGrad[i+j-1].first].push_back(m_nodGrad[i-1].first);
                }
            }
            else
            {
                out<<"-1";
                return;
            }
            sort(m_nodGrad.begin()+i, m_nodGrad.end(),cmp);
            /*for(int i=0;i<m_nrNoduri;i++)
                cout<<m_nodGrad[i].second;
            cout<<'\n';
            for(int i=0;i<m_nrNoduri;i++)
                cout<<m_nodGrad[i].first;
            cout<<"\n\n";*/
        }
        int ok = 1;
        for(int i=0;i<m_nrNoduri;i++)
        {
            if(m_nodGrad[i].second != 0)
                ok = 0;
        }
        if(ok==1)
        {
            for(int i = 1; i <= m_nrNoduri; i++)
            {
                out<<i<<": ";
                for(int j = 0; j < m_list[i].size(); j++)
                {
                    out<<m_list[i][j]<<' ';
                }
                out<<'\n';
            }
        }
        else
        {
            out<<"-1";
            return;
        }

    }
    else
    {
        out<<"-1";
        return;
    }
}

void Graf::ctc_Kosoraju()
{

    in>>m_nrNoduri>>m_nrMuchii;
    for(int i=0;i<m_nrMuchii;i++)
    {
        int x,y;
        in>>x>>y;
        m_list[x].push_back(y);
        listAux[y].push_back(x);
    }
    for(int i=1;i<=m_nrNoduri;i++)
    {
        if(m_viz[i]==0)
        {
            r_dfs(i);
        }

    }
    for(int i=1;i<=m_nrNoduri;i++)
    {
        m_list[i].clear();
        for(int j=0;j<listAux[i].size();j++)
        {
            m_list[i].push_back(listAux[i][j]);
        }
    }
    /*for(int i=1;i<=m_nrNoduri;i++)
    {
        cout<<i<<": ";
        for(int j=0;j<listAux[i].size();j++)
        {
            cout<<m_list[i][j]<<' ';
        }
        cout<<'\n';
    }*/
    for(int i=0; i<=m_nrNoduri;i++)
        m_viz[i]=0;
    for(int i=m_stiva.size()-1;i>=0;i--)
    {
        if(m_viz[m_stiva[i]]==0)
        {
            nrTC++;
            rr_dfs(m_stiva[i]);
        }


    }
    out<<nrTC<<'\n';
    for(int i = 1; i <= nrTC; i++)
    {
        for(int j = 0; j < tareConexe[i].size();j++)
            out<<tareConexe[i][j]<<' ';
        out<<'\n';
    }


}

void Graf::dijkstra()
{
    int contor = 0;
    in>>m_nrNoduri>>m_nrMuchii;
    for(int i=2;i<=m_nrNoduri;i++)
    {
        m_q[i]=1<<30;

    }
    m_q[1]=0;
    for(int i=1;i<=m_nrMuchii;i++)
    {
        int x,y,z;
        in>>x>>y>>z;
        v[x].push_back(y);
        d[x].push_back(z);
    }
    s.insert(make_pair(0,1));
    contor++;
    while(contor>0)
    {
        int w,q;
        w=s.begin()->first;
        q=s.begin()->second;
        if(m_viz[q]==1)
        {
            s.erase(s.begin());
            contor--;
        }
        else
        {
            m_viz[q]=1;
            int minim=1<<30;
            for(int i=0;i<v[q].size();i++)
            {
                if(m_q[v[q][i]]>m_q[q]+d[q][i])
                {

                    m_q[v[q][i]]=m_q[q]+d[q][i];
                    s.insert(make_pair(m_q[v[q][i]],v[q][i]));
                    contor++;

                }

            }
        }

    }
    for(int i=2;i<=m_nrNoduri;i++)
    {
        if(m_q[i]==1<<30)
            out<<"0 ";
        else
            out<<m_q[i]<<' ';
    }

}
void Graf::disjoint() {


    int n,m;
    in>>n>>m;
    for(int i=0; i<=n;++i) //parent 0 = 0 redundant(nu avem nod 0)
    {
        m_parent.push_back(i);
        m_rank.push_back(0);
    }

    for(int i=1;i<=m;++i)
    {
        int c,x,y; //cerinta,x,y
        in>>c>>x>>y;
        if(c==1)
        {
            this->union_(x, y);
        }
        if(c==2)
        {
            if(this->find(x) == this->find(y))
                out<<"DA\n";
            else
                out<<"NU\n";
        }


    }
}

int Graf::find(int x) {
    if(m_parent[x] != x)
        m_parent[x] = find(m_parent[x]);
    return m_parent[x];
}

void Graf::union_(int x, int y) {
    // gasesc reprezentantul multimii pt x si y
    int repx = find(x);
    int repy = find(y);
    if(repx == repy) return; //deja in aceeasi multime

    if(m_rank[repx] < m_rank[repy]) //leg multimea mai mica de multimea mai mare
        m_parent[repx] = repy;
    else if(m_rank[repy] < m_rank[repx])
        m_parent[repy] = repx;
    else                            //daca sunt egale leg y de x si rank x creste
    {
        m_parent[repy] = repx;
        m_rank[repx]++;
    }


}

void Graf::kruskal() {
    in>>m_nrNoduri>>m_nrMuchii;
    vector<edge> muchii,raspuns;
    int costTotal = 0;
    for(int i=0; i<=m_nrNoduri;++i) //parent 0 = 0 redundant(nu avem nod 0)
    {
        m_parent.push_back(i);
        m_rank.push_back(0);
    }

    for(int i=0;i<m_nrMuchii;i++)
    {
        int x,y,c;
        in>>x>>y>>c;
        edge aux;
        aux.x = x;
        aux.y = y;
        aux.cost = c;
        muchii.push_back(aux);
    }
    sort(muchii.begin(),muchii.end(),cmp_edge);
    for(int i=0;i<m_nrMuchii;++i)
    {
        if(this->find(muchii[i].x) != this->find(muchii[i].y))
        {
            raspuns.push_back(muchii[i]);
            costTotal += muchii[i].cost;
            union_(muchii[i].x, muchii[i].y);
        }

    }
    out<<costTotal<<'\n'<<raspuns.size()<<'\n';
    for (int i = 0; i < raspuns.size(); ++i) {
        out<<raspuns[i].x<<' '<<raspuns[i].y<<'\n';
    }
}