codeforces Rumor

题意

大意是在一个城市里,N个人,有M对盆友关系,题目所给1~N数据的值是从编号1~N所对应的市民要让他们相信并且散播所需要的金钱,盆友之间传播谣言不用花费钱。现在我想散播谣言让这座城市的每个人都知道。最后我们要得出把谣言散播满整个城市所需要的最小金钱。

思路

同样这是一并查集,额。。。刚刚敲完大脑短路,急需冷却CD,日后再补。。。

code

#include<stdio.h>

int pre[100050];
__int64 gold[100050];

int Find(int x)     //这是一个普通的查找
{
    int r=x;

    while(pre[r]!=r)
    {
        r=pre[r];
    }

    int i=x,j;

    while(pre[i]!=r)
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }

    return r;
}

int beyondFind(int x) //这是一个超越的查找。。。
{
    int r=x;
    int Count=0;

    while(pre[r]!=r)
    {
        r=pre[r];
        Count++;
    }

    if(Count!=0)
        return 0;
    else
        return r;
}

void join(int a,int b) //这相当于构造一个个的树,树的根是每棵树的最小结点
{
    int tx,ty;
    tx=Find(a);
    ty=Find(b);

    if(tx!=ty)
    {
        int x,y;
        x=gold[tx];
        y=gold[ty];

        if(x<=y)
            pre[ty]=tx;
        else
            pre[tx]=ty;
    }
}

int main()
{
    int n,m;

    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%I64d",&gold[i]);

        for(int i=1;i<=n;i++)
        {
            pre[i]=i;
        }

        int a,b;

        while(m--)
        {
            scanf("%d%d",&a,&b);
            join(a,b);
        }

        __int64 sum=0;         //注意数据类型
        for(int i=1;i<=n;i++)
        {
            int t;
            t=beyondFind(i);
            sum+=gold[t];
        }
        printf("%I64d\n",sum);
    }
    return 0;
}

Accept 了很开心,但是这代码啥时候敲的完啊。。。俺有点 >﹏< 那啥。。

猜你喜欢

转载自blog.csdn.net/LaoXiangQ/article/details/84146228