數據中心(最小生成樹)(csp201812-4)

在這裏插入圖片描述在這裏插入圖片描述

Sample input

4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2

Sample output

4

樣例說明

在這裏插入圖片描述
在這裏插入圖片描述

解題思路

乍一看題目很長很複雜,其實仔細讀題後可以發現題目的真正問題是:對一個加權無向圖,求解一個最大邊權最小的樹結構。

最大值最小問題我們可以用二分答案來做,但是這個題沒有必要,這是一個裸的kruskal,直接記錄最後一個加入最小生成樹的邊即可。因爲使用kruskal開始將邊的權值從小到大排了一次序,最後一個加入最小生成樹的變一定是能加入的最大邊權中最小的(再小邊就不夠了)。

完整代碼

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;

const int maxn=50000+10;
struct node
{
    int x,y,w;
};
node a[maxn*2];
int par[maxn],rnk[maxn],ans;
void init(int n)
{
    for (int i=0; i<=n; i++)
    {
        par[i]=i;
        rnk[i]=1;
    }
}
int find(int x)
{
    return par[x]==x ? x : par[x]=find(par[x]);
}
bool unite(int x,int y)
{
    x=find(x); y=find(y);
    if(x==y) return false;

    if(rnk[x]>rnk[y]) swap(x,y);
    par[x]=y; rnk[y]+=rnk[x]; rnk[x]=rnk[y];
    return true;
}
int getint()
{
    int x=0,s=1;
    char ch=' ';
    while(ch<'0' || ch>'9')
    {
        ch=getchar();
        if(ch=='-') s=-1;
    }
    while(ch>='0' && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*s;
}
bool comp(node a,node b)
{
    return a.w<b.w;
}
int main()
{
    int n=getint(),m=getint(),root=getint();

    for (int i=1; i<=m; i++)
    {
        a[i].x=getint(); a[i].y=getint(); a[i].w=getint();
    }
    sort(a+1,a+1+m,comp);

    int tot=0;
    init(n);
    for (int i=1; i<=m; i++)
    {
        if(unite(a[i].x,a[i].y))
        {
            tot++; ans=a[i].w;
        }
        if(tot==n-1)
            break;
    }
    printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章