#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int MAXN=100000;
const int MAXM=200000;
const int INF=(1<<30);
ll dis[MAXN],mini=-1,re;
int n,m,len=0,last[MAXN],fa[MAXN],pre[MAXN];
int cur,pos;
bool vis[MAXN];
struct edge{
int u,v,w;
friend bool operator < (const edge &x,const edge &y){
return x.w<y.w;
}
}e[MAXM];
int Find(int x){
return x==fa[x]?x:fa[x]=Find(fa[x]);
}
struct Edge{
int next,to,val;
Edge(int n=0,int v=0,int w=0):next(n),to(v),val(w){}
}E[MAXN];
void add(int from,int to,int val){
E[++len]=Edge(last[from],to,val);last[from]=len;
E[++len]=Edge(last[to],from,val);last[to]=len;
}
void kruskal(){
ll ans=0;
fo(i,1,n) fa[i]=i;
sort(e+1,e+1+m);
fo(i,1,m){
int x=Find(e[i].u),y=Find(e[i].v);
if(x==y) continue;
else{
ans+=e[i].w;
add(e[i].u,e[i].v,e[i].w);
fa[x]=y;
}
}
printf("%lld\n",ans);
}
void dfs(int x){
for(int i=last[x];i;i=E[i].next){
int id=E[i].to;
if(!vis[id]){
pre[id]=x;
dis[id]=dis[x]+E[i].val;
vis[id]=true;
dfs(id);
vis[id]=false;
}
}
}
void search(int x){
if(pre[x]) search(pre[x]);
re=min(re,max(dis[x],mini-dis[x]));
}
int main(){
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
fo(i,1,m) {
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
}
kruskal();
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
vis[1]=true;
dfs(1);
fo(i,1,n){
if(dis[i]>mini) mini=dis[cur=i];
}
vis[1]=false;
memset(pre,0,sizeof(pre));
memset(dis,0,sizeof(dis));
vis[cur]=true;
dfs(cur);
mini=-1;
fo(i,1,n){
if(dis[i]>mini) mini=dis[pos=i];
}
re=mini;
search(pos);
printf("%lld",re);
return 0;
}codevs 1700 MST和树的重心
最新推荐文章于 2024-07-01 10:25:42 发布
本文介绍了一种使用Kruskal算法构建最小生成树的方法,并在此基础上寻找图的直径。通过两次深度优先搜索确定图中两个最远的顶点,进而计算图的直径。
695

被折叠的 条评论
为什么被折叠?



