AT_abc355_f MST Query 题解
Tag:最小生成树
原题链接
题目大意
给你一棵
思路
这道题我们观察题目范围,可知权值的范围很小。所以我们考虑枚举权值,计录这种权值的边对答案的变化
对于一条边,我们用并查集记录这条边加进去会不会构成环。
-
如果这条边不会构成环且不在最小生成树内,则加入这条边,变化量加上这条边的权值。
-
如果这条边构成环且在最小生成树内,则去掉这条边,变化量减去这条边的权值。
最后对
代码
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
int n,q;
int a[500005],b[500005],c[500005],dp[500005];
int num[500005];
int fa[500005];
int find(int x)
{
if(fa[x]==x) return x;
fa[x]=find(fa[x]);
return fa[x];
}
bool merge(int x,int y)
{
int xx=find(x),yy=find(y);
if(xx==yy) return false;
if(num[xx]>num[yy]) swap(xx,yy);
num[yy]+=num[xx];
fa[xx]=yy;
return true;
}
bool fl[500005];
signed main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n+q-1;i++)
{
cin>>a[i]>>b[i]>>c[i];
}
for(int i=1;i<=10;i++)
{
for(int j=1;j<=200005;j++)
{
fa[j]=j;
num[j]=1;
}
for(int j=1;j<=n+q-1;j++)
{
if(c[j]<=i)
{
if(merge(a[j],b[j]))
{
if(!fl[j])
{
fl[j]=1;
dp[j]+=i;
}
}
else
{
if(fl[j])
{
dp[j]-=i;
fl[j]=0;
}
}
}
}
}
for(int i=1;i<=n+q-1;i++) dp[i]+=dp[i-1];
for(int i=n;i<=n+q-1;i++)
{
cout<<dp[i]<<"\n";
}
return 0;
}
本文作者:yaaaaaan
本文链接:https://www.cnblogs.com/yaaaaaan/p/18577000
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步