【基础算法】铲雪车问题(BZOJ1190)

来源:互联网 发布:斗鱼狗贼的淘宝店 编辑:程序博客网 时间:2024/04/27 14:20

问题 L(1190): 【基础算法】铲雪车问题

时间限制: 1 Sec  内存限制: 64 MB
提交: 132  解决: 56
[提交][状态][我的提交]

题目描述

大雪覆盖了整座城市,市政府要求冬季服务部尽快将一些街道(列在一份清单中)的积雪清除掉以恢复交通。整个城市由许多交叉路口和街道构成,当然任意两个交叉路口都是直接或间接连通的。清单给出了最少的街道,使得这些街道的积雪清除后任意两个交叉路口之间有且仅有一条通路。冬季服务部门只有一辆铲雪车和一名司机,这辆铲雪车的出发点位于某个交叉路口。无论街道上有没有积雪,铲雪车每前进一米都要消耗一升燃料。冬季服务部门要求司机在铲除清单上的所有街道的积雪的前提下,消耗燃料最少,铲完后车可以停在任意交叉路口。

输入

输入:第一行包含2个整数N,S。(1 < =N < = 100000,1 < = S < =N).N 为交叉路口总数,S为铲雪车出发的路口序号。路口的标号为1...N。接下来的N-1行为清单上的街道,每一行包含三个用空格隔开的整数A,B,C,表示一条从交叉路口A到交叉路口B的街道,C为该街道的长度。单位为米,1 < = C < =1000.

输出

输出:仅一行,包含一个整数,表示铲掉所有积雪所需的最少燃料。

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

5 11 2 81 3 103 4 104 5 7

样例输出

43
分析:首先这个图两个点之间只有一条路,且n个点,n-1条边,所以这是一棵树。然后因为要让走过的路最短而除了最后一次为前面每次走到叶子节点后都要返回根,所以把所有权值的和乘2再减去树上的最长路即可。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>using namespace std;struct bian{    int v,w,next;}arr[400010];int fir[200010],n,r,start,end,c,cnt,sum;bool vis[200010];int dfs(int x){    vis[x]=1;    int ans=0;    for(int i=fir[x];i;i=arr[i].next){        if(vis[arr[i].v])   continue ;        int tmp=dfs(arr[i].v)+arr[i].w;        ans=max(tmp,ans);    }    return ans;}int main(){    scanf("%d %d",&n,&r);    for(int i=1;i<n;i++){        scanf("%d %d %d",&start,&end,&c),sum+=c;        arr[++cnt].v=end,arr[cnt].w=c,arr[cnt].next=fir[start];        fir[start]=cnt;        arr[++cnt].v=start,arr[cnt].w=c,arr[cnt].next=fir[end];        fir[end]=cnt;    }    printf("%d",sum*2-dfs(r));}  

0 0
原创粉丝点击