D - 数据中心
题目描述
Sample Input
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
Sample Output
4
题解
由"一个树结构传输图的传输时间是Tmax,其中Tmax=max(Th),h为接收点在树中的深度,Th是接收点的深度为h的所有边中最长的边的长度"可知,我们要找的最优树结构流水线耗时Tmax就是找最小连通树中的最长边的值,不用考虑这个边在第几层,也不用考虑这棵树的具体结构,只要是这棵连通树的最大边是所有连通树中最小的(最小的最大值)就行了。
用kruskal算法和并查集的方法找最小连通树。
用堆(vector存储的)存放所有的边,par数组存放并查集关系,most存放连通图里最长的边。
取出堆顶点尝试将这条边所在的两个点合并,并在可以合并时更新most的值,这样most中存储的就一直是目前连通图中的最大边。
最后most就是Tmax,输出。
代码
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
struct edge{
int u,v,w;
bool operator<(const edge&e)const{
return w>e.w;
}
};
vector<edge> v;
int n;//有多少个点 1~n
int most;//最大的边
int par[50010];
void init(){//初始化
for(int i=0;i<=n;i++){par[i]=i;}
}
int find(int x){
return (par[x]==x)?x:(par[x]=find(par[x]));
}
void unite(int x,int y,int w){
x=find(x),y=find(y);
if(x==y){return;}
par[x]=y;
most=w;
}
int main(int argc, char** argv) {
int m,root;//边数 根
scanf("%d%d%d",&n,&m,&root);
for(int i=1;i<=m;i++){
int u1,u2,w;
scanf("%d%d%d",&u1,&u2,&w);
v.push_back({u1,u2,w});
}
make_heap(v.begin(),v.end());
init();
while(!v.empty()){
edge e=v[0];//由0改为1
pop_heap(v.begin(), v.end());
v.pop_back();
unite(e.u,e.v,e.w);
}
printf("%d\n",most);
return 0;
}