2024-8-20模拟赛T2

image

提交题目链接

题意:

\(n\) 个点,每个点有相应的权值,用 \(m\) 条边将点连接形成多个联通块,按某种顺序依次删除这 \(n\) 个点,求每次操作后,全部的连通块中总权值的最大值。

解析:

将依次删点变为依次加点,并在加点时用并查集维护权值,然后更新最大权值。

插嘴:

看似简单的题其实有许多坑,像我考试时就没有思路,听到讲解才发现其实这题我做过类似的(菜),然后根据解析调代码时还调不出。

跟着代码学学吧!!只要脑子不抽其实这题很简单的!! 我好菜

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+10;
int n,m;
int fa[N];
vector<int> v[N];
ll val[N];
int z[N];
ll jg[N];
int pre[N];
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
int main(){
freopen("qd.in","r",stdin);
freopen("qd.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;
cin>>val[i];
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
int x;
ll ans=0;
stack<int> r;
for(int i=1;i<=n;i++){
cin>>pre[i];
}
for(int i=n;i>=2;i--){
x=pre[i];
z[x]=1;
for(int i=0;i<v[x].size();i++){
if(z[v[x][i]]==1){
if(find(v[x][i])!=find(x)){
int xx=find(x),yy=find(v[x][i]);
fa[yy]=fa[xx];
val[xx]+=val[yy];
}
}
}
ans=max(ans,val[find(x)]);
jg[i-1]=ans;
}
for(int i=1;i<=n;i++){
cout<<jg[i]<<"\n";
}
return 0;
}
/*
6 7
1 1 4 5 1 4
1 2
3 4
4 5
5 6
3 6
3 5
4 6
4 5 3 6 1 2
*/
posted @   sad_lin  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示