数据中心(最小生成树)(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章