贪心+SPFA——游

4 篇文章 0 订阅

问题背景

zhx和他的妹子出去玩。


问题描述

zhx和他的妹子去一个国家旅游,共有N个旅游景点,N-1条双向连接的道
路将它们联通起来,每一条道路有固定长度。一开始zhx位于1号景点。 
现在希望你能够求出旅行长度最小的方案,使得每个景点至少被访问到一次。


输入格式

第一行两个整数N,代表景点数目。 
接下来 N-1行,每行三个整数s,t,w表示有一条从s到t的双向道路,长度为w。s和t的编号从1开始。 


输出格式


1 2 3 
2 3 3 


样例输出


样例输入


1 2 3 
1 3 3


样例输出


数据规模与约定

对于30%的数据,1≤N≤10。 

对于70%的数据,1 ≤ N ≤ 1000。 
对于100%的数据,1≤N≤50000,1≤w≤1000。 

一行一个整数,代表能够访问每个景点至少一次的方案的最小旅行长度


思路

画图(如下图)可知:
最小旅行长度=树上所有边总长度*2-距离1号节点最远的节点距1号节点的距离
[求点距1号节点的距离可用SPFA]


代码(C++)

#include <queue>
#include <cstdio>
#include <bitset>
#define N 50010
#define M 100010
using namespace std;
int n,u,v,w,pos,he[N],en[M],ne[M],len[M],cnt=0;
long long ans=0,m=0,dis[50010];
const long long inf=9223372036854775807ll;
bitset<N> in;	queue<int> q;
inline void add();
int main()
{
	scanf("%d",&n);
	for(int i=2;i<=n;++i)
		scanf("%d%d%d",&u,&v,&w),add(),
		ans+=2*w,dis[i]=inf;
	q.push(1);	in[1]=1;
	while(!q.empty())
	{
		pos=q.front(); q.pop(); in[pos]=0;
		for(int k=he[pos];k;k=ne[k])
			if(dis[pos]+len[k]<dis[en[k]])
			{
				dis[en[k]]=dis[pos]+len[k];
				if(!in[en[k]])
					in[en[k]]=1,q.push(en[k]);
			}
	}
	for(int i=1;i<=n;++i)
		if(dis[i]>m)
			m=dis[i];
	printf("%lld",ans-m);
	return 0;
}
inline void add()
{
	en[++cnt]=v;	len[cnt]=w;
	ne[cnt]=he[u];	he[u]=cnt;
	en[++cnt]=u;	len[cnt]=w;
	ne[cnt]=he[v];	he[v]=cnt;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值