1. 程式人生 > >URAL-1982-Electrification Plan最小生成樹或並查集

URAL-1982-Electrification Plan最小生成樹或並查集

ural 理解 生成 color algo 大小 span 不用 一個個

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最小生成樹或並查集