【SSL 1463】旅行
题目大意:
一颗 \(n\) 个节点的树,一段路径的长度是每个点一奇一偶取相反数,求这棵树内经过道路数为奇数的 \(k\) 短路。
正文:
搜索出每一个节点到根节点的长度 \(dis_i\),然后树的奇偶层分成两个部分,然后两个部分进行匹配。
题目大意:
struct edge
{
ll from, to, next, w;
}e[N];
ll head[N], tot, total;
struct node
{
ll val, dep;
}dis[N];
struct recc
{
ll x, y, len;
};
bool operator <(const recc &a, const recc &b)
{
return a.len > b.len;
}
priority_queue <recc> que;
void add(ll u, ll v, ll w)
{
e[++tot] = (edge){u, v, head[u], w}, head[u] = tot;
}
int cmp (node a, node b)
{
if((a.dep & 1) == (b.dep & 1)) return a.val < b.val;
return (a.dep & 1) < (b.dep & 1);
}
void dfs(ll fa, ll x, ll step, ll isneg) // Get dis
{
dis[x].dep = step;
for (int i = head[x]; i; i = e[i].next)
{
int y = e[i].to;
if(fa == y) continue;
dis[y].val = isneg * e[i].w + dis[x].val;
dfs (x, y, step + 1, -isneg);
}
if(step & 1) dis[x].val = -dis[x].val;
}
int main()
{
scanf ("%lld%lld", &n, &m);
for (int i = 1; i < n; i++)
{
ll u, v, w;
scanf ("%lld%lld%lld", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
dfs(0, 1, 1, 1);
sort (dis + 1, dis + 1 + n, cmp);
ll dis2pos = 0;
for (int i = 1; i <= n; i++) if(dis[i].dep % 2 == 1){dis2pos = i;break;}
que.push((recc){1, dis2pos, dis[1].val + dis[dis2pos].val});
for (int i = 1; i < m; i++)
{
if(que.empty()) break;
recc a = que.top();
que.pop();
if(a.x < (dis2pos - 1) && a.y == dis2pos)
que.push((recc){a.x + 1, dis2pos, dis[a.x + 1].val + dis[dis2pos].val});
if(a.y < n)
que.push((recc){a.x, a.y + 1, dis[a.x].val + dis[a.y + 1].val});
}
if(que.empty())
puts("Stupid Mike");
else
printf("%lld", que.top().len);
return 0;
}