题目描述
解题思路
题目大意:
给出顶点数,边数,再输入若干条边,求出若干条边满足条件:
1)这几条边中长度最大的长度尽量小;
2)这若干条边可保证图的连通性;
3)在1,2的基础上,求个MST
Kruscal算法求出的生成树满足一个特性:这个生成树的最长边是尽量短的.
参考代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#define MAX_N 1010
#define MAX_E 15010
using namespace std;
int par[MAX_N];
int rank[MAX_N];
struct edge{
int u,v,cost;
}es[MAX_E];
int V,E;
bool cmp(const edge& e1,const edge& e2){
return e1.cost < e2.cost;
}
void init(){
for (int i = 0;i < V;++i){
par[i] = i;
rank[i] = 0;
}
}
int find(int x){
if (par[x] == x) return x;
else return par[x] = find(par[x]);
}
void unite(int x,int y){
x = find(x);
y = find(y);
if (x == y) return ;
if (rank[x] < rank[y]) par[x] = y;
else{
par[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
bool same(int x,int y){
return (find(x) == find(y));
}
void Kruskal(){
sort(es,es+E,cmp);
init();
int res = 0,opr = 0,i;
for (i = 0;i < E;++i){
edge e = es[i];
if (!same(e.u,e.v)){
unite(e.u,e.v);
res += e.cost;
opr++;
}
if(opr == V-1) break;
}
printf("%d\n%d\n",es[i].cost,i+1);
for (int j = 0;j <= i;++j)
printf("%d %d\n",es[j].u,es[j].v);
}
int main()
{
scanf("%d %d",&V,&E);
for (int i = 0;i < E;++i){
scanf("%d %d %d",&es[i].u,&es[i].v,&es[i].cost);
}
Kruskal();
return 0;
}