版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wingrez/article/details/88588667
数据中心
来源:CCF
标签:最小生成树
参考资料:
相似题目:
题目
输入样例
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
输出样例
4
样例解释
题目大意
给你一个由一些顶点、边、权值组成的无向连通图,让你在其中找出一棵树,要求该树结构满足以下条件:
1、所有结点都与根结点连通
2、该树的处于同一深度上的边的最大权值记为Th
3、该树的所有深度上的Th的最大值记为Tmax
4、Tmax是所有树结构中Tmax的最小值
请通过“样例解释”加以理解。
解题思路
仔细思考,其实就是求最小生成树。
参考代码
#include<cstdio>
#include<vector>
#include<queue>
#define MAXN 50005
using namespace std;
struct Edge{
int v,u;
int t;
bool operator < (const Edge &e) const {
return t>e.t;
}
};
vector<Edge> adj[MAXN]; //agj[v]:与v相连的边
priority_queue<Edge> pq; //优先队列,存放横切边
vector<Edge> mst; //最小生成树
bool vis[MAXN]; //访问标志
void Prim(); //Prim算法,计算最小生成树
void visit(int v); //设置访问标志,并将与v相邻结点(未被访问)的边加入优先队列中
void Prim(){
visit(1);
while(!pq.empty()){
Edge e=pq.top();
pq.pop();
if(vis[e.v] && vis[e.u]) continue;
mst.push_back(e);
if(!vis[e.v]) visit(e.v);
if(!vis[e.u]) visit(e.u);
}
}
void visit(int v){
vis[v]=true;
for(vector<Edge>::iterator i=adj[v].begin(); i!=adj[v].end();i++){
if(!vis[(*i).u]){
pq.push(*i);
}
}
}
int main(){
int n,m,root;
int v,u,t;
Edge e;
scanf("%d%d%d",&n,&m,&root);
for(int i=0;i<m;i++){
scanf("%d%d%d",&v,&u,&t);
e.v=v; e.u=u; e.t=t;
adj[v].push_back(e);
e.v=u; e.u=v;
adj[u].push_back(e);
}
Prim();
int ans=0;
for(vector<Edge>::iterator i=mst.begin();i!=mst.end();i++){
ans= ans>(*i).t? ans : (*i).t;
}
printf("%d\n",ans);
return 0;
}