最小生成树版子题不多说,上代码
#include <bits/stdc++.h>
using namespace std;
const int N=305; //题目数据范围
int f[N]; //father数组
int deep[N]; //并查集的优化,记录小挂大
int rfind(int x) { //查询返回根节点的值,优化后回溯过程中会将节点直接挂在根节点下
if (x==f[x])return x; //如果自己就是自己祖先,代表找到根节点,返回
return f[x] = rfind(f[x]); //向上递归,找祖先
}
void merge(int x,int y) { //合并函数
if (rfind(x)==rfind(y))return; //如果根节点相同代表已经在一个集合中
x=rfind(x);
y=rfind(y); //二者都找寻自己的根节点
if (deep[x]>deep[y]) f[y]=x;
else if (deep[x]<deep[y]) f[x]=y;
else f[x]=y,deep[y]++; //按照小挂大原则合并根节点,相同深度deep数组对应节点的值要+1
}
struct edge {
int u;
int v;
int w;
edge(int u,int v,int w) {
this->u=u;
this->v=v;
this->w=w;
}
};
int main() {
int n,m;cin >> n >> m;
vector<edge> edges; //存储边的数组
while (m--) {
int u,v,w;cin >> u >> v >> w;
edges.emplace_back(u,v,w);
}
sort(edges.begin(),edges.end(),[](auto a,auto b) {
return a.w < b.w;
}); //不需要建图,将边按权排序
int sum=0;
for (int i=1;i<=n;i++) {
f[i]=i;
deep[i]=1;
} //初始化
for (auto e : edges) { //从小到大遍历
if (rfind(e.u) != rfind(e.v)) {
merge(e.v,e.u); //可以合并两个节点就合并
sum = max(sum,e.w);
} //最终一定是一个最小生成树
}
cout << n-1 << " " << sum << endl;
}

京公网安备 11010502036488号