URAL-1982-Electrification Plan最小生成树或并查集

Posted ckxkexing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了URAL-1982-Electrification Plan最小生成树或并查集相关的知识,希望对你有一定的参考价值。

Electrification Plan

题意:在一个无向图中,给你几个源点,找出把所有点连接到源点后最小的消费;

可以利用并查集:

  先用结构体把每个边存起来,再按照消费大小排序。之后从消费小的到大的一个个尝试,两个点需要连接的话,连接上同时把消费也算上去;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
const int inf = 0x3f3f3f;

using namespace std;

int n,k;
int fa[10000+7];
struct node 
{
    int from,to;
    int c;
}a[10007];
bool cmp(node a,node b)
{
    return a.c<b.c;
}
void init(){
    for(int i=1;i<=n;i++)
        fa[i] = i;
}
int find(int x)
{
    if(fa[x]==x)return x;
    else return fa[x] = find(fa[x]);
}
int uni(int x,int y)
{
    if(fa[x]==-1&&fa[y]==-1)return 0;        //(**)
    int px = find(x);
    int py = find(y);
    if(px==py)return 0;
    else 
    {
        fa[px] = py;
        return 1;
    }
}

int main(){
    scanf("%d%d",&n,&k);
    init();
    for(int i=1;i<=k;i++)
    {
        int x;
        scanf("%d",&x);
        fa[x]=-1;                //这个操作我其实不是很明确,我以我的理解加上了(**)这句,
    }                            //表示源点之间不用连接,但是别人写的好像不用加这句话。
    int cnt =0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int cost;
            scanf("%d",&cost);
            if(cost==0)continue;
            a[++cnt].c=cost;
            a[cnt].from = i;
            a[cnt].to =j;
        }
    }
    sort(a+1,a+1+cnt,cmp);
    int ans = 0;
    for(int i=1;i<=cnt;i++)
    {
        if(uni(a[i].from,a[i].to))
        {
            ans += a[i].c;
        }
    }
    printf("%d\n",ans);
    return 0;
}

 我自己就做了一个预处理,(直接把读入的用uni连接起来

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
const int inf = 0x3f3f3f;

using namespace std;

int n,k;
int fa[10000+7];
struct node 
{
    int from,to;
    int c;
}a[10007];
bool cmp(node a,node b)
{
    return a.c<b.c;
}
void init(){
    for(int i=1;i<=n;i++)
        fa[i] = i;
}
int find(int x)
{
    if(fa[x]==x)return x;
    else return fa[x] = find(fa[x]);
}
int uni(int x,int y)
{
    int px = find(x);
    int py = find(y);
    if(px==py)return 0;
    else 
    {
        fa[px] = py;
        return 1;
    }
}

int main(){
    scanf("%d%d",&n,&k);
    init();
    int last=-1;
    for(int i=1;i<=k;i++)
    {
        int x;
        scanf("%d",&x);
        if(last!=-1)
        {
            int suibian;
            suibian =uni(last,x);                //不理解别人把fa[x]=-1的操作;
            last = x;                            //自己就先预处理连接好了;
        }
        else last=x;
    }                            
    int cnt =0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int cost;
            scanf("%d",&cost);
            if(cost==0)continue;
            a[++cnt].c=cost;
            a[cnt].from = i;
            a[cnt].to =j;
        }
    }
    sort(a+1,a+1+cnt,cmp);
    int ans = 0;
    for(int i=1;i<=cnt;i++)
    {
        if(uni(a[i].from,a[i].to))
        {
            ans += a[i].c;
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

以上是关于URAL-1982-Electrification Plan最小生成树或并查集的主要内容,如果未能解决你的问题,请参考以下文章