hdu1879最小生成树+并查集

#include<iostream>

#include<vector>

#include<queue>

#include<cstdio>



using namespace std;



struct edge

{

    int from,to,cost;

    friend bool operator <(edge e1,edge e2)

    {

        return e1.cost>e2.cost;

    }

};

const int MAXN=111;

int u[MAXN];

vector<edge>v[MAXN];

bool selected[MAXN];

//bool select_e[MAXN][MAXN];

int find(int p)

{

    if(u[p]==p)

    {

        return p;

    }else

    {

        return u[p]=find(u[p]);

    }

}

void connect(int a,int b)

{

    int f1=find(a);

    int f2=find(b);

    int i=0;

    if(f1<f2)

    {

        u[f2]=f1;

        for(i=0;i<=int(v[f2].size())-1;i++)

        {

            v[f1].push_back(v[f2][i]);

        }

    }else

    {

        u[f1]=f2;

        for(i=0;i<=int(v[f1].size())-1;i++)

        {

            v[f2].push_back(v[f1][i]);

        }

    }

}

int prim(int p)

{

    priority_queue<edge>q;

    int sum=0;

    p=find(p);

    selected[p]=1;

    int i=0;

    while(!q.empty())

    {

        q.pop();

    }

    for(i=0;i<=int(v[p].size())-1;i++)

    {

        int to=find(v[p][i].to);

        if(!selected[to])

        {

            q.push(v[p][i]);

        }

    }

    while(!q.empty())

    {

        int from;

        int i=0;

        int to;

        edge e=q.top();

        to=find(e.to);

        from=find(e.from);

        q.pop();

        if(!selected[to])

        {

            sum=sum+e.cost;

            selected[to]=1;

            for(i=0;i<=int(v[to].size())-1;i++)

            {

                int too=find(v[to][i].to);

                if(!selected[too])

                {

                    q.push(v[to][i]);

                }

            }

        }

    }

    return sum;

}

void init(int n)

{

    int i=0;

    for(i=0;i<=n;i++)

    {

        v[i].clear();

    }

    memset(selected,0,sizeof(selected));

//    memset(select_e,0,sizeof(select_e));

    for(i=0;i<=n;i++)

    {

        u[i]=i;

    }

}

int main()

{

    int n;

    while((scanf("%d",&n))&&(n!=0))

    {

        int from,to,cost,builded;

        init(n);

        int i=0;

        n=(n*(n-1))/2;

        for(i=0;i<=n-1;i++)

        {

            scanf("%d%d%d%d",&from,&to,&cost,&builded);

            from=find(from);

            to=find(to);

            if(builded)

            { 

                connect(from,to);

            }else

            {

                edge e={from,to,cost};

                v[e.from].push_back(e);

                swap(e.from,e.to);

                v[e.from].push_back(e);

            }

        }

        cout<<prim(find(1))<<endl;

    }

    return  0;

}

  

你可能感兴趣的:(最小生成树)