Minimum spanning tree for each edge题解
原题在这里
题意:给定一张图,求:
对于每条边,求包含这条边的最小生成树的权值的和。
思路:
先把最小生成树算出来,对于每条边,如果这条边包含在最小生成树里,则不变。否则如果这条边的两个点是
代码:
#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int>
using namespace std;
const int N=2e5;
int n,m;
struct edge{
int x,y,w,id;
}e[N+5];
vector<PII> v[N+5];
int sum=0;
int ans[N+5];
bool vis[N+5];
int pre[N+5];
int find(int x){return pre[x]==x?x:pre[x]=find(pre[x]);}
void Kruscal()
{
for(int i=1;i<=n;i++) pre[i]=i;
for(int i=1;i<=m;i++)
{
int fx=find(e[i].x);
int fy=find(e[i].y);
if(fx==fy) continue;
sum+=e[i].w;
vis[e[i].id]=1;
pre[fx]=fy;
v[e[i].x].push_back({e[i].y,e[i].w});
v[e[i].y].push_back({e[i].x,e[i].w});
}
}
int dep[N+5];
int lca[N+5][31];
int RMQ[N+5][31];
void dfs(int node,int father)
{
dep[node]=dep[father]+1;
lca[node][0]=father;
for(int j=1;j<=30;j++)
{
lca[node][j]=lca[lca[node][j-1]][j-1];
RMQ[node][j]=max(RMQ[node][j-1],RMQ[lca[node][j-1]][j-1]);
}
for(auto son:v[node])
{
if(son.first==father) continue;
RMQ[son.first][0]=son.second;
dfs(son.first,node);
}
}
int query(int x,int y)
{
if(dep[x]>dep[y]) swap(x,y);
int res=0;
for(int j=30;j>=0;j--)
{
if(dep[lca[y][j]]>=dep[x])
{
res=max(res,RMQ[y][j]);
y=lca[y][j];
}
}
if(x==y) return res;
for(int j=30;j>=0;j--)
{
if(lca[x][j]!=lca[y][j])
{
res=max(res,max(RMQ[x][j],RMQ[y][j]));
x=lca[x][j];
y=lca[y][j];
}
}
return max(res,max(RMQ[x][0],RMQ[y][0]));
}
bool cmp(edge a,edge b){return a.w<b.w;}
bool CMP(edge a,edge b){return a.id<b.id;}
signed main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>e[i].x>>e[i].y>>e[i].w;
e[i].id=i;
}
stable_sort(e+1,e+m+1,cmp);
Kruscal();
dfs(1,0);
stable_sort(e+1,e+m+1,CMP);
for(int i=1;i<=m;i++)
{
cout<<sum-query(e[i].x,e[i].y)+e[i].w<<"\n";
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】