Cod sursa(job #2807271)

Utilizator asdfsfafafafafafafafaJarca Andrei asdfsfafafafafafafafa Data 23 noiembrie 2021 16:54:48
Problema Arbore partial de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 9.28 kb
	
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <bits/stdc++.h>
#include<algorithm>

using namespace std;
//ifstream fin("bfs.in");
//ofstream fout("bfs.out");
//ifstream fin("dfs.in");
//ofstream fout("dfs.out");
//ifstream fin("biconex.in");
//ofstream fout("biconex.out");
//ifstream fin("ctc.in");
//ofstream fout("ctc.out");
//ifstream fin("sortaret.in");
//ofstream fout("sortaret.out");
//ifstream fin("helsinki.in");
//ofstream fout("helsinki.out");
//ifstream fin("disjoint.in");
//ofstream fout("disjoint.out");
ifstream fin("apm.in");
ofstream fout("apm.out");
int viz[100001];
int first_value[100001];
int min_pos[100001];
stack <int> node_order;
int counter=0;
vector<int>biconex[100001];
vector<int>ctc[100001];
vector<int>sol_ctc[100001];
vector<int>sol_sortaret;
vector<int>hel;
vector<vector<int>>sol;
vector<int>graf[100001];
int tree[100001];
int height[100001];
int rang[100001];
int idx[100001];
vector<int>sol_kruskal;
int X[100001],Y[100001],C[100001];
class grafMare
{
    int N,M;
    vector <int> graf[100001];
    public:
        grafMare(){};
        int get_N();
        void citireBFS();
        void citireDFS();
        void actualDFS(int);
        void citire_biconex();
        void add_a_biconex(int,int);
        void DFS_biconex(int,int,int);
        void citireCTC();
        void DFS_CTC_1(int);
        void DFS_CTC_2(int);
        void citire_top();
        void DFS_top(int);
        bool helsinki();
        void citire_helsinki();
        void tarjan(int current_node, int current_pos, int tata_node)
        {
            min_pos[current_node]=current_pos;
            first_value[current_node]=current_pos;
            for(auto i : graf[current_node])
            {
                if(!min_pos[i])
                {
                    tarjan(i, current_pos+1, current_node);
                    min_pos[current_node]=min(min_pos[current_node],min_pos[i]);
                    if(min_pos[i]>current_pos)
                        sol.push_back({current_node,i});
                }
                else if(i!=tata_node)
                    min_pos[current_node]=min(min_pos[current_node],first_value[i]);
            }
        }
        vector<vector<int>> criticalConnections(int n, vector<vector<int>>& connections)
        {
            //first_value = vector<int>(n);
            //min_pos = vector<int>(n);
            for(auto x : connections)
            {
                graf[x[0]].push_back(x[1]);
                graf[x[1]].push_back(x[0]);
            }
            tarjan(0,1,-1);
            return sol;
        }
        void citire_pmd();
        int radacina(int);
        void combine(int,int);
        void pmd_out();
        void combine_apm_kruskal(int,int);
        void citire_apm_kruskal();
};
void grafMare::combine_apm_kruskal(int x,int y)
{
    tree[x]=y;
}
bool sortare(int x,int y)
{
    return C[x]<C[y];
}
void grafMare::citire_apm_kruskal()
{
    int rez=0;
    fin>>N>>M;
    for(int i=1;i<=M;i++)
    {
        fin>>X[i]>>Y[i]>>C[i];
        tree[i]=i;
        idx[i]=i;
    }
    sort(idx+1,idx+M+1,sortare);
    for(int i=1;i<=M;i++)
    {
        if(radacina(X[idx[i]]) != radacina(Y[idx[i]]) )
        {
            rez+=C[idx[i]];
            combine_apm_kruskal(radacina(X[idx[i]]),radacina(Y[idx[i]]));
            sol_kruskal.push_back(idx[i]);
        }
    }
    fout<<rez<<N-1;
    for(int i=0;i<N-1;i++)
        fout<<X[sol_kruskal[i]]<<Y[sol_kruskal[i]]<<"\n";
}
void grafMare::citire_pmd()
{
    fin>>N>>M;
	for(int i=1;i<=N;i++)
		tree[i]=i;
	for(int i=1;i<=N;i++)
		rang[i]=1;
}
int grafMare::radacina(int x)
{
    while(tree[x]!=x)
        x=tree[x];
    return x;
}
void grafMare::combine(int x,int y)
{
    if(rang[x]==rang[y])
    {
        tree[y]=x;
        rang[x]++;
    }
    else if(rang[x]>rang[y])
        tree[y]=x;
    else
        tree[x]=y;
}
void grafMare::pmd_out()
{
    int a,x,y;
    for(int i=0;i<M;i++)
    {
        fin>>a>>x>>y;
        if(a==1)
            combine(radacina(x),radacina(y));
        else
        {
            if(radacina(x)==radacina(y))
                fout<<"DA\n";
            else
                fout<<"NU\n";
        }
    }
}
bool grafMare::helsinki()
{
    while(1)
    {
        sort(hel.begin(),hel.end(),greater<>());
        if(hel[0]==0)//toate 0
            return true;
        int x=hel[0];
        hel.erase(hel.begin());
        if(x>hel.size())//destule elem
            return false;
        for(int i=0;i<x;i++)
        {
            hel[i]--;
            if(hel[i]<0)//gasit elem negativ
                return false;
        }
    }
}
void grafMare::citire_helsinki()
{
    fin>>N;
    for(int i=0;i<N;i++)
    {
        int x;
        fin>>x;
        hel.push_back(x);
    }
    fout<<helsinki();
    
}
void grafMare::DFS_top(int current_node)
{
    viz[current_node]=1;
    for(auto x : graf[current_node])
        if(!viz[x])
            DFS_top(x);
    sol_sortaret.push_back(current_node);
}
void grafMare::citire_top()
{
    fin>>N>>M;
    for(int i=0;i<M;i++)
    {
        int a,b;
        fin>>a>>b;
        graf[a].push_back(b);
    }
    for(int i=1;i<=N;i++)
        if(!viz[i])
            DFS_top(i);
    reverse(sol_sortaret.begin(),sol_sortaret.end());
    for(auto x : sol_sortaret)
        fout<<x<<" ";
}
void grafMare::citireCTC()
{
    fin>>N>>M;
    for(int i=0;i<M;i++)
    {
        int a,b;
        fin>>a>>b;
        graf[a].push_back(b);
        ctc[b].push_back(a);
    }
    for(int i=1;i<=N;i++)
        if(!viz[i])
            DFS_CTC_1(i);
    while(!node_order.empty())
    {
        if(viz[node_order.top()]==1)
        {
            counter++;
            DFS_CTC_2(node_order.top());
        }
        node_order.pop();
    }
    fout<<counter<<"\n";
    for(int i=1;i<=counter;i++)
    {
        for(auto x : sol_ctc[i])
            fout<<x<<" ";
        fout<<"\n";  
    }
}
void grafMare::DFS_CTC_1(int current_node)
{
    viz[current_node]=1;
    for(auto x : graf[current_node])
        if(!viz[x])
            DFS_CTC_1(x);
    node_order.push(current_node);
}
void grafMare::DFS_CTC_2(int current_node)
{
    viz[current_node]=2;
    sol_ctc[counter].push_back(current_node);
    for(auto x : ctc[current_node])
        if(viz[x]==1)
            DFS_CTC_2(x);
}
int grafMare::get_N()
{
    return N;
}
void grafMare::citire_biconex()
{
    fin>>N>>M;
    for(int i=0;i<M;i++)
    {
        int a,b;
        fin>>a>>b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }
}
void grafMare::DFS_biconex(int current_node, int current_pos, int tata_node)
{
    min_pos[current_node]=current_pos;
    first_value[current_node]=current_pos;
    node_order.push(current_node);
    for(auto i : graf[current_node])
    {
        if(!min_pos[i]) //dfs
        {   
            DFS_biconex(i, current_pos+1, current_node);
            min_pos[current_node]=min(min_pos[current_node],min_pos[i]);
            // actualizez levelul minim in caz ca baiatul urmator are traseu mai scurt de la un nod mai devreme, dupa ce intra in else if(desen 2, 7-8, 1-8)
            if(min_pos[i] >= current_pos) // asta e punct de articulatie, daca n ar respecta cond asta, ins ca exista alt traseu care mentine conditia cu conex
            {
                counter++;
                //current_node e first si i duce la ult elem din stack
                while(node_order.top()!=i)
                {
                    biconex[counter].push_back(node_order.top());
                    node_order.pop();
                }
                biconex[counter].push_back(node_order.top());
                node_order.pop();
                biconex[counter].push_back(current_node);
            }
        }
        else if(i!=tata_node)
            min_pos[current_node]=min(min_pos[current_node],first_value[i]);
    }
}
void grafMare::citireBFS()
{
    fin>>N>>M;
    int start;
    fin>>start;
    int a,b;
    for(int i=0;i<M;i++)
    {
        fin>>a>>b;
        graf[a].push_back(b);
    }
    int sol[100001];
    for(int i=0;i<N+1;i++)
        sol[i]=-1;
    queue <int> q;
    q.push(start);
    sol[start]=0;
 
    while(!q.empty())
    {
        int first=q.front();
        q.pop();
        for(int vecin : graf[first])
        {
            if(sol[vecin]==-1)
            {
                sol[vecin]=sol[first]+1;
                q.push(vecin);
            }
        }
    }
    for(int i=1;i<N+1;i++)
        fout<<sol[i]<<" ";
}
void grafMare::actualDFS(int index)
{
    for(int vecin : graf[index])
        if(!viz[vecin])
        {
            viz[vecin]=1;
            actualDFS(vecin);
        }
}
void grafMare::citireDFS()
{
    fin>>N>>M;
    int start=1;
    int a,b;
    for(int i=0;i<M;i++)
    {
        fin>>a>>b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }
    for(int i=0;i<N+1;i++)
        viz[i]=0;
    for(int i=1;i<N+1;i++)
        if(!viz[i])
        {
            counter++;
            actualDFS(i);
        }
    fout<<counter;
}
int main()
{
    grafMare gm;
    //gm.citireBFS();
    gm.citire_apm_kruskal();
}