SP368 CSTREET - Cobbled streets 題解

zsfzmxl發表於2024-08-21

題意

選 n−1 條道路連線 n 個城市,且使得其修建的價格最小。

分析

最小生成樹的模板題,可以用 kruskal 來做。

首先,先將所有的邊權從小到大排序。

然後,取當前沒有選過的,且邊權最小的邊,判斷它連線的兩個點是否同屬一個集合,如果不是就把他們加到同一個集合中,再記錄答案。

程式碼很簡單,也很容易理解。

struct node{
    int from,to,w;
}e[N*N/2];
void init(){
    for(int i=1;i<=n;i++)f[i]=i;
}
int find(int x){
    if(x==f[x])return x;
    return f[x]=find(f[x]);
}
void un(int x,int y){
    int fx=find(x);
    int fy=find(y);
    if(fx==fy)return ;
    else f[fx]=fy; 
}
bool cmp(node x,node y){
    return x.w<y.w;
}
int kruskal(){
    sort(e+1,e+m+1,cmp);
    int sum=0,cnt=0;//sum權值之和,cnt加入邊數
    for(int i=1;i<=m;i++){
        if(find(e[i].from)!=find(e[i].to)){
            un(e[i].from,e[i].to);
            sum+=e[i].w*p;
            cnt++;
            if(cnt==n-1)return sum;
        }
    } 
    return -1;
}