uva6437 Power Plantuva6437 Power Plantuva6437 Power Plantuva6437 Power Plantuva6437 Power Plant

uva6437 Power Plant

uva6437 Power Plant

uva6437 Power Plant

#include<cstdio>

#include<algorithm>

#include<iostream>

#include<cstring>

#define N 100090

using namespace std;

int n,m,t;

int pre[N];

struct node

{

    int st,ed,val;

}e[N];

void init()

{

    for(int i=0;i<=205;i++)

    {

        pre[i]=i;

    }

}

int cmp(node a,node b)

{

    return a.val<b.val;

}//从小到大排序

int Find(int m)

{

    int n=m;

    while(n!=pre[n])

        n=pre[n];

    //pre[m]=n;

    return n;

}//查找根节点

void Merge(int x,int y)

{

    int fx=Find(x);

    int fy=Find(y);

    if(fx>fy)

        pre[fx]=fy;

    else

        pre[fy]=fx;

}

int kruskal(int l)

{

    int sum=0,cnt=t-1;

    for(int i=0;i<l;i++)

    {

        if(Find(e[i].st)!=Find(e[i].ed))

        {

            cnt++;

            Merge(e[i].st,e[i].ed);

            sum+=e[i].val;

            //printf("%d %d相连\n",e[i].st,e[i].ed);

            //printf("%d的根节点是%d\n",e[i].st,Find(e[i].st));

            //printf("%d的根节点是%d\n",e[i].ed,Find(e[i].ed));

        }

        if(cnt==n-1)

            break;

    }

    return sum;

}

int main()

{

    int T,k=1;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d%d%d",&n,&m,&t);

        init();

        int a[N];

        for(int i=0;i<t;i++)

        {

            scanf("%d",&a[i]);

            if(i!=0)

            {

                Merge(a[i],a[i-1]);

                //printf("%d和%d相连\n",a[i],a[i-1]);

                //printf("%d的根节点是%d\n",a[i-1],Find(a[i-1]));

                //printf("%d的根节点是%d\n",a[i],Find(a[i]));

            }

        }

        for(int i=0;i<m;i++)

        {

            scanf("%d%d%d",&e[i].st,&e[i].ed,&e[i].val);

        }

        sort(e,e+m,cmp);

        printf("Case #%d: %d\n",k++,kruskal(m));

    }

    return 0;

}

 

 

题目大意:和基本的最小生成树想比,其在最开始的时候有多个起点,从任一起点开始生成都可以。提前把根节点都连起来就行了 ,剩下的和求最小声生成树一样。

注意:初始化问题。



相关文章: