直接替代码及注释吧
#include<iostream>
#include<algorithm>
using namespace std;
struct side
{
int spot1, spot2, value;//起始点,边的价值
};
int n, m,f[10010];
bool cmp(side a, side b)//定义一个sort排序
{
if (a.value <= b.value)
return true;
else
return false;
}
int find(int x)//并查集模板,查找父节点
{
if (x == f[x]) return x;
f[x] = find(f[x]);
return f[x];
}
side fa[10010];
bool check(int k)//判断当前二分的道路的分值是否能满足将所有路口遍历完
{
for (int i = 1; i <= n; i++)
f[i] = i; //初始化并查集
for (int i = 1; i <= m; i++)
{
if (fa[i].value > k)//如果分值已经大于二分的值了,后面就不能要了
break;
if (find(fa[i].spot1) != find(fa[i].spot2))//如果他们的父节点不是一个(即他们没有连通)
f[find(fa[i].spot1)] = find(fa[i].spot2);//就将他们的父节点连通
}
int fin = 0;
for (int i = 1; i <= n; i++)//循环遍历判断这些道路能不能连通全部路口
{
if (f[i] == i)//如果这一个节点没有被改变(即f[i]==i),fin++
fin++;
}
if (fin == 1)//有且仅有一个节点没有被改变,说明所有道路已经联通了
return true;
return false;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> fa[i].spot1 >> fa[i].spot2 >> fa[i].value;
sort(fa + 1, fa + m + 1, cmp);
int l = fa[1].value, r = fa[m].value;//二分的区间
while (l < r)//二分查找最小的那个分值
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
int ans = l;
int res;
//这里可以数学推断出res=n-1
cout << n-1<< ' ' << ans;
return 0;
}
这一题主要是用二分找到最大的最小分值,然后是用并查集判断是否连通