小美是美团的一名鲜花快递员,鲜花是一种保质期非常短的商品,所以需要尽快送到客户手中,公司对于骑手的一个要求就是要规划送花的线路,使得骑手送完所有订单走的路程尽可能少。(骑手开始派送时带走了所有需要派送的花,不必每单后返回花店,路程结算是从花店出发,到送完最后一名客户为止,不计算从最后一名客户家回到花店的时间)
公司对于骑手的绩效评价是取决于两个指标,一是从花店到所有客户地址的距离之和,另一个是骑手实际走的路程。
设花店始终位于1号位置,客户共有n-1个,其编号为2~n。令dis(i,j)表示i号位置到j号位置的距离,即分别计算
, 和骑手实际所走的最短路程。
为了简化问题,我们约束这n个位置构成的是一棵树,即只有n-1条边在其中互相连接,且保证n个点彼此连通。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
输入描述:
输出第一行包含一个正整数n,即花店和客户的总数。(1<=n<=30000)
接下来有n-1行,每行有三个整数u,v,w,表示在u和v之间存在一条距离为w的道路。(1<=w<=1000)
输出描述:
输出包含两个整数,中间用空格隔开,分别表示花店到所有客户地址的距离之和和骑手实际走的路程。
示例1
输入例子:
5
1 2 3
1 3 1
1 4 2
2 5 1
输出例子:
10 10
#include <climits>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
struct Node {
int dis = 0;
vector<pair<int, int>> edges;
};
vector<Node> nodes;
int dissum = 0;
int walksum=0;
int maxdis=0;
void dfs(int now, int pre) {
// cout<<now<<pre<<endl;
for (auto& edge : nodes[now].edges) {
if (edge.first != pre) {
walksum+=edge.second*2;
int len = nodes[now].dis + edge.second;
// if(len<nodes[edge.first].dis){
nodes[edge.first].dis = len;
// cout<<len<<endl;
dissum += len;
maxdis=max(maxdis,len);
dfs(edge.first,now);
// }
}
else continue;
}
return;
}
int main() {
int n;
cin >> n;
nodes.resize(n + 1);
for (int i = 1; i <n; i++) {
int u, v, w;
cin >> u >> v >> w;
pair<int, int> tempu(v, w);
nodes[u].edges.push_back(tempu);
pair<int, int> tempv(u, w);
nodes[v].edges.push_back(tempv);
}
nodes[1].dis = 0;
//深搜查看每个顾客到花店的距离
dfs(1, 0);
cout<<dissum<<' '<<walksum-maxdis<<endl;
return 0;
}
// 64 位输出请用 printf("%lld")