2021ICPC上海 H.Life is a Game(kruskal重构树)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021ICPC上海 H.Life is a Game(kruskal重构树)相关的知识,希望对你有一定的参考价值。

2021ICPC上海 H.Life is a Game(kruskal重构树)

原图建最小kruskal重构树,预处理倍增 边权最值和fa数组,结点值表示该子树叶子节点权值和即可。

时间复杂度: O ( ( n + q ) l o g n ) O((n+q)logn) O((n+q)logn)

// Problem: Life is a Game
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/24872/H
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// Date: 2021-11-30 13:41:54
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+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,q;
int s[N];
int f[N][20];
int cost[N][20];
int a[N];
struct edge
	int u,v,w;
	bool operator<(const edge&e)const
		return w<e.w;
	
e[N<<1];
int find(int x)
	return s[x]==x?x:s[x]=find(s[x]);

void init(int n)
	rep(i,1,n) s[i]=i;

int cnt;
void kruskal()
	cnt=n;init(n<<1);
	int tot=0;
	rep(i,1,m)
		int u=e[i].u,v=e[i].v,w=e[i].w;
		u=find(u),v=find(v);
		if(u!=v)
			a[++cnt]=a[u]+a[v];
			s[u]=s[v]=cnt;
			f[u][0]=f[v][0]=cnt;
			cost[u][0]=w-a[u];
			cost[v][0]=w-a[v];
			++tot;
		
		if(tot==n-1) break;
	

int main()
	scanf("%d%d%d",&n,&m,&q);
	rep(i,1,n) scanf("%d",&a[i]);
	rep(i,1,m)
		scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
	
	sort(e+1,e+m+1);
	kruskal();
	a[0]=a[cnt];
	int lg = log2(cnt)+1;
	rep(j,1,lg)
		rep(i,1,cnt)
		
			f[i][j]=f[f[i][j-1]][j-1];
			cost[i][j]=max(cost[i][j-1],cost[f[i][j-1]][j-1]);
		
	while(q--) 
		int x,k;scanf("%d%d",&x,&k);
		for(int i=lg;~i;i--) if(cost[x][i]<=k) x=f[x][i];
		printf("%d\\n",a[x]+k);
	
	return 0;


以上是关于2021ICPC上海 H.Life is a Game(kruskal重构树)的主要内容,如果未能解决你的问题,请参考以下文章

2021 ICPC上海 H.Life is a Game(Kruskal重构树)

2021 ICPC上海 H.Life is a Game(Kruskal重构树)

2021 ICPC上海 H.Life is a Game(Kruskal重构树)

2021ICPC上海 H.Life is a Game (kruskal重构树倍增)

2021上海ICPC--H.Life is a Game--Kruskal重构树--铜牌拦路虎

2021 ICPC上海 I.Steadily Growing Steam(dp)