Cod sursa(job #1443973)

Utilizator 13pisicinegreFMI Pal Paula Alexandra 13pisicinegre Data 29 mai 2015 02:19:48
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.98 kb
#include <iostream>
#include <fstream>
#include <utility>
#include <set>
#include <vector>
#include <algorithm>


using namespace std;
struct comp3
{
    bool operator()(vector<int> a,vector<int> b)
    {
        if(a[0]<b[0])
            return true;
        return false;
    }
}c3;
bool com(vector<int> a,vector<int> b)
    {
        if(a[0]==b[0])
            return true;
        return false;
    }
struct comp{
bool operator () (pair<vector<int>,int> a,pair<vector<int>,int> b)
{
    //ordoneaza mai intai dupa ponderi
    if(a.second<b.second)
        return true;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            if(a.first[i]<b.first[i])
                return true;
    return false;
}
};
struct comp2{
bool operator () (pair<vector<int>,int> a,pair<vector<int>,int> b)
{
    //ordoneaza mai intai dupa nod
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            if(a.first[i]<b.first[i])
                return true;
    if(a.second<b.second)
        return true;
    return false;
}
};
class gf
{
    int n; //nr vf
    set<pair<vector<int>,int>, comp>E; //muchiile
    public:
    gf():n(0)
    {
    }
    gf(gf &m)
    {
        n=m.n;
        E=m.E;
    }
friend ostream &operator <<(ostream &,const gf &);
friend istream &operator >>(istream &,gf &);
friend class arbore_prim;
friend class arbore_kruskal;
};
istream &operator >> (istream &in,gf &m)
{
    vector<int> v;
    in>>m.n;
    int p,a,b,c;
    in>>p;
    while(p)
    {
        p--;
        in>>a;
        v.push_back(a);
        in>>b>>c;
        v.push_back(b);
        m.E.insert(make_pair(v,c));
        v.clear();
    }
}

ostream &operator <<(ostream & out,const gf &m)
{
    for(set<pair<vector<int>,int> >::iterator j=m.E.begin();j!=m.E.end();j++)
        out<<(*j).first[0]<<" "<<(*j).first[1]<<" "<<(*j).second<<endl;
}

class arbore_kruskal
{
    int n;
    int suma;
    set<pair<int,int> > m;
public:
    arbore_kruskal():n(0){}
    arbore_kruskal(int noduri, set<pair<int, int> >muchii):n(noduri),m(muchii){};
    arbore_kruskal(arbore_kruskal &A){n=A.n; m=A.m;}
    arbore_kruskal kruskal(gf G);
    int reuniune(vector<int> &a,int u, int v);
    int gaseste(vector<int> &a,int i,int &h);
    friend ostream &operator <<(ostream &,const arbore_kruskal &);
};
ostream &operator <<(ostream & out,const arbore_kruskal &a)
{
    out<<a.suma<<endl;
    out<<a.m.size()<<endl;
    for(set<pair<int,int> >::iterator j=a.m.begin();j!=a.m.end();j++)
        out<<(*j).first<<"  "<<(*j).second<<endl;
}
arbore_kruskal arbore_kruskal::kruskal(gf g)
{
    cout<<"Kruskal"<<endl;
    arbore_kruskal a;
    int suma=0;
    vector<int> v; //creez cate un arbore distinct pentru fiecare varf
    for(int j=0;j<=g.n;j++)
    {
        v.push_back(-1);
    }
    int l,m;
    for(set<pair<vector<int>,int> >::iterator i=g.E.begin();i!=g.E.end();i++)
    {
        if(gaseste(v,(*i).first[0],l)!=gaseste(v,(*i).first[1],m))
        {
            a.n++;
            a.m.insert(make_pair((*i).first[0],(*i).first[1]));
            reuniune(v,(*i).first[0],(*i).first[1]);
            suma=suma+(*i).second;
            if(a.n==(g.n-1))
                i=g.E.end();
        }
    }

    a.suma=suma;
    return a;
}
int arbore_kruskal::gaseste(vector<int> &a,int i,int &h)
{
    h=0;//distanta de la nod la radacina
    int rad,var;
    for(rad=i;a[rad]!=-1;rad=a[rad]);
    for(;a[i]!=-1;)
    {
        h++;
        //compresia drumurilor
        var=a[i];
        a[i]=rad;
        i=var;

    }
    return rad;
}

int arbore_kruskal::reuniune(vector<int> &a,int u, int v)
{
    int h1,h2;
    u=gaseste(a,u,h1);
    v=gaseste(a,v,h2);
    if(h1>h2)
        a[v]=u;
    else
        a[u]=v;
    return 0;
}

int main()
{
    gf g;
    fstream in("apm.in",ios::in);
    in>>g;
    in.close();
    arbore_kruskal k;
    fstream out("apm.out",ios::out);
    out<<k.kruskal(g);
    return 0;
}