title: 2019牛客国庆集训派对 H-Highway (dijk求树的直径(当然还有更优的))
categories: 2019牛客国庆集训派对
top: false
tags:
acm
树的直径
题目大意
n个点从1-n, 有(n - 1)条边连接。
现在要重新修(n - 1)条路, 修i 到 j 所用的代价为i到j的最短路,
问最多的代价是多少
分析
就是求树的直径, 然后跑两边最短路求其他点到直径两端点的最短路, 最后把最大值加起来就可。
AC代码
#include
using namespace std;
typedef long long ll;
typedef pair P;
const int INF = 0x3f3f3f3f;
const ll llINF = 0x3f3f3f3f3f3f3f3f;
const int mod = int(1e9) + 7;
const int N = int(1e5) + 10;
struct edge{
int u, v, ne;
ll w;
}ed[2 * N];
int n, cnt, head[N];
ll dis1[N], dis2[N];
bool vis[N];
void init(){
cnt = 0;
memset(head, -1, sizeof head);
}
void add(int u, int v, ll w){
ed[cnt].u = u, ed[cnt].v = v, ed[cnt].w = w, ed[cnt].ne = head[u];
head[u] = cnt++;
}
int dijk(ll dis[], int st){
for (int i = 1; i <= n; i++)
dis[i] = ll(1e15);
memset(vis, false, sizeof vis);
priority_queue, greater >q;
dis[st] = 0;
q.emplace(0, st);
while(!q.empty()){
int u = q.top().second;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u]; ~i; i = ed[i].ne){
int v = ed[i].v;
if (dis[v] > dis[u] + ed[i].w){
dis[v] = dis[u] + ed[i].w;
q.emplace(dis[v], v);
}
}
}
ll ans = 0, ansj;
for (int i = 1; i <= n; ++i){
if (dis[i] != ll(1e15) && dis[i] > ans){
ans = dis[i], ansj = i;
}
}
return ansj;
}
int main() {
std::ios::sync_with_stdio(0);
int a, b;
ll c;
while(cin >> n){
init();
for (int i = 0; i < n - 1; ++i){
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
int s1 = dijk(dis1, 1);
int s2 = dijk(dis1, s1);
dijk(dis1, s1);
dijk(dis2, s2);
ll ans = dis1[s2];
for (int i = 1; i <= n; i++){
if (i == s1 || i == s2)
continue;
ans += max(dis1[i], dis2[i]);
}
cout << ans <<"\n";
}
return 0;
}
、
恰似你一低头的温柔,娇弱水莲花不胜寒风的娇羞, 我的心为你悸动不休。 --mingfuyan

京公网安备 11010502036488号