#E. 滑雪与时间剂

#E. 滑雪与时间剂

  • 题意

有N个点,每个点有自己的高度,只能从高处到低处

如果一条边两边高度不同,则路为单向,否则为双向

他可以随时回到之前的任意一点,从1点出发,在满足到的点尽可能多的情况下求最小距离

  • 分析

对于任意点来说,只能从比他更高(或一样高)的点走到

所以按照高度作为第一关键字排序,再跑最小生成树即为答案

  • 细节

先要跑一遍DFS,确定可到个数后再跑最小生成树

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,h[5000000],vis[5000000],cnt,ans,fa[5000000];
ll head[5000000],tot,toto;
struct nood{
	ll v;
	ll w;
	ll lz;//来自哪里 
	ll nxt;
}es[5000000];
struct nood1{
	ll x;
	ll y;
	ll w;
}es1[5000000];
void adde(ll x,ll y,ll z){
	es[++tot].v=y,es[tot].w=z,es[tot].lz=x,es[tot].nxt=head[x],head[x]=tot;
}
void dfs(ll x){
	vis[x]=1;
	cnt++;
	for(int i=head[x];i;i=es[i].nxt){
		ll v=es[i].v;
		if(!vis[v]){
			dfs(v);
		}
	}
}
int find(int x){
	if(fa[x] == x) 
		return x;
	return fa[x] = find(fa[x]);
}
void merge(ll x,ll y){
	ll xx=find(x);
	ll yy=find(y);
	if(xx!=yy){
		fa[xx]=yy;
	}
}
bool cmp(nood1 a,nood1 b){
	if(h[a.y]==h[b.y]){
		return a.w<b.w;
	}
	return h[a.y]>h[b.y];
}
void kru(){
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	sort(es1+1,es1+toto+1,cmp);
	for(int i=1;i<=toto;i++){
		if(find(es1[i].x)!=find(es1[i].y)){
			ans+=es1[i].w;
			//fa[find(es1[i].x)]=fa[es1[i].y];
			merge(es1[i].x,es1[i].y);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>h[i];
	}
	ll x,y,z;
	for(int i=1;i<=m;i++){
		cin>>x>>y>>z;
		if(h[x]>=h[y]){
			adde(x,y,z);
		}
		if(h[x]<=h[y]){
			adde(y,x,z);
		}
	}
	dfs(1);
	for(int i=1;i<=tot;i++){
		if(vis[es[i].lz]&&vis[es[i].v]){
			es1[++toto].x=es[i].lz;
			es1[toto].y=es[i].v;
			es1[toto].w=es[i].w;
			//cout<<es1[toto].w<<" "<<es1[toto].x<<" "<<es1[toto].y<<endl;
		}
	}
	kru();
	cout<<cnt<<" "<<ans;
}
posted @   MistyPost  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示