CCF计算机软件能力认证试题练习:201812-4 数据中心

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/wingrez/article/details/88588667