[ABC252E] Road Reduction 题解

文章介绍了如何使用Dijkstra算法在一个给定的无向连通简单图中找到最小生成树,最小化点1到其他所有点的距离和,同时输出生成树的边的编号。通过维护每个点到1的最短路径,选择边时优先考虑距离最短且未被优化过的边。
摘要由CSDN通过智能技术生成

题意简述

给定 $ n $ 个点 $ m $ 条边的无向连通简单图,每条边为 $ a_i $ 到 $ b_i $,权值为 $ c_i $。你需要构造一棵生成树,最小化点 $ 1 $ 在生成树上到其它所有点的距离和,输出生成树的所有边的序号。如果有多个方案随便输出一个即可。

解题思路

我们令 d i s i dis_i disi 表示 1 1 1 i i i 的最短路的长度, D i D_i Di 表示在某种选择的方案下 1 1 1 i i i 的长度。不难发现一定会有 D i ≥ d i s i D_i \geq dis_i Didisi。所以,在选择某一条边后,如果有 D i = d i s i D_i=dis_i Di=disi,那么选择这条边就是最优的。选边的过程可以在跑 dijkstra 的过程中顺便完成掉。具体细节见代码及注释。

代码示例

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
	int v,w,id;//id表示边的编号
	bool operator<(const node &b)const{
		return w>b.w;//方便priority_queue从小到大排序
	}
};
vector<node> G[200010];
int n,m,ans[200010],dis[200010];
priority_queue<node> q;
void Dijkstra(){
	memset(dis,0x3f,sizeof(dis));
	q.push({1,0,0});
    //其实q中不需要记录边的编号,这里偷了个懒,沿用了前面的结构体
	dis[1]=0;
    //初始化
	while(!q.empty()){
		int u=q.top().v,D=q.top().w;
		q.pop();
		if(dis[u]<D) continue;
        //没有这个判断将会在after_contest的数据上TLE。我也不知道为什么会TLE,但是加上绝对是正确的。(如有大佬知道可以告诉我qwq)
		for(int i=0;i<G[u].size();i++){
			int v=G[u][i].v,w=G[u][i].w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				ans[v]=G[u][i].id;//记录答案
				q.push({v,dis[v],0});
			}
		}
	}
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		G[u].push_back({v,w,i});
		G[v].push_back({u,w,i});
	}
	Dijkstra();
	for(int i=2;i<=n;i++) cout<<ans[i]<<" ";
	cout<<endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值