2024-8-20模拟赛T2
提交题目链接
题意:
有 \(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 */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具