P2573 [SCOI2012]滑雪(kruskal&bfs)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2573 [SCOI2012]滑雪(kruskal&bfs)相关的知识,希望对你有一定的参考价值。
P2573 [SCOI2012]滑雪(kruskal&bfs)
这个时间胶囊相当于每个边只用走一次,也就是答案对应的图的边权之和。
考虑从1开始 b f s bfs bfs能走的点和边,建立一个新图,然后在新图跑 k r u s k a l kruskal kruskal即可。
排序的时候 h v h_v hv为第一关键字, w w w为第二关键字。
因为要求点数尽量多,所以 h v h_v hv尽量大,在此基础上要求权最小即可。
时间复杂度: O ( n l o g n + m ) O(nlogn+m) O(nlogn+m)
// Problem: P2573 [SCOI2012]滑雪
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2573
// Memory Limit: 125 MB
// Time Limit: 5000 ms
// Date: 2021-12-17 11:06:56
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
int n,m,H[N];
int h[N],cnt;
struct edge
int to,nt,w;
e[M<<1];
struct E
int u,v,w;
bool operator<(const E&a)const
return H[v]==H[a.v]?w<a.w:H[v]>H[a.v];
a[M<<1];
void add(int u,int v,int w)
e[++cnt]=v,h[u],w,h[u]=cnt;
int sum,num;
bitset<N>vis;
void bfs()
queue<int>q;q.push(1);sum++;vis[1] = 1;
while(!q.empty())
int u = q.front();q.pop();
for(int i=h[u];i;i=e[i].nt)
int v = e[i].to;
a[++num] = u,v,e[i].w;
if(!vis[v])
q.push(v),vis[v] = 1;
sum++;
int s[N];
int find(int x)
return x==s[x]?x:s[x]=find(s[x]);
int main()
scanf("%d%d",&n,&m);
rep(i,1,n) scanf("%d",&H[i]),s[i] = i;
rep(i,1,m)
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(H[u]>=H[v]) add(u,v,w);
if(H[v]>=H[u]) add(v,u,w);
bfs();
int x = 0;
ll ans = 0;
sort(a+1,a+num+1);
rep(i,1,num)
int u = a[i].u,v=a[i].v,w=a[i].w;
u=find(u),v=find(v);
if(u!=v)
s[u] = v;
ans+=w;
x++;
if(x==sum - 1) break;
printf("%d %lld\\n",sum,ans);
return 0;
以上是关于P2573 [SCOI2012]滑雪(kruskal&bfs)的主要内容,如果未能解决你的问题,请参考以下文章