【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行

题目





若不存在第\(k\)短路径时,输出“Stupid Mike”

题解

题意

给出一个有\(n\)个点的树

问这\(n\)个点两两之间经过道路为奇数的第\(k\)短的路径长度是多少

路径长度特别定义(见题面)

分析

根据题目

很显然当两个点之间的道路为奇数时

肯定一个点的深度是奇数,另一个是偶数

再看一下路径

一条合法路径长度:\(x-x+x-x+x\)……(不要管数字,只注意符号)

可以发现,开头和结尾都是\(+\)

那么我们可以将每个点按照正负正负的顺序求出到根节点(1)的路径

换句话说,从根节点(1)往每个点走,走到\(x\)节点计算它的长度为\(-dis[fa(父亲)]+len(当前这条边的长度)\)

求出\(dis\)之后

把深度为奇数的\(dis\)放到\(a\)

把深度为偶数的\(dis\)放到\(b\)

然后这个问题就转化成了如何求\(a[i]+b[j]\)的第\(k\)小值

建个小根堆

把所有的\(a[i]+b[1]\)放入堆中

每次取出最小的\(a[i]+b[j]\)

放入\(a[i]+b[j+1]\)

最后答案就是第\(k\)次取出的数

Code

#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
long long head,to,val,next;
}a[200005];
struct dui
{
long long val,idi,idj;
}d[200005];
long long n,k,i,x,y,z,n1,n2,num,tot,ans,ans1,ans2,deep[100005],dis[100005],d1[100005],d2[100005];
void add(long long x,long long y,long long z)
{
tot++;
a[tot].to=y;
a[tot].val=z;
a[tot].next=a[x].head;
a[x].head=tot;
}
void dfs(long long now,long long fa)
{
long long i,x;
for (i=a[now].head;i;i=a[i].next)
{
x=a[i].to;
if (x==fa) continue;
deep[x]=deep[now]+1;
dis[x]=-dis[now]+a[i].val;
dfs(x,now);
}
}
void up(long long x)
{
long long t;
while (x>1&&d[x>>1].val>d[x].val)
{
t=d[x].val;
d[x].val=d[x>>1].val;
d[x>>1].val=t;
t=d[x].idi;
d[x].idi=d[x>>1].idi;
d[x>>1].idi=t;
t=d[x].idj;
d[x].idj=d[x>>1].idj;
d[x>>1].idj=t;
x>>=1;
}
}
void down(long long x)
{
long long t,y;
y=x<<1;
while ((y<=num&&d[y].val<d[x].val)||(y+1<=num&&d[y+1].val<=d[x].val))
{
if (y+1<=num&&d[y].val>d[y+1].val) y++;
t=d[x].val;
d[x].val=d[y].val;
d[y].val=t;
t=d[x].idi;
d[x].idi=d[y].idi;
d[y].idi=t;
t=d[x].idj;
d[x].idj=d[y].idj;
d[y].idj=t;
x=y;
y=x<<1;
}
}
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
scanf("%lld%lld",&n,&k);
for (i=1;i<n;i++)
{
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
deep[1]=0;
dis[1]=0;
dfs(1,0);
for (i=1;i<=n;i++)
{
if (deep[i]%2==1)
{
n1++;
d1[n1]=dis[i];
}
else
{
n2++;
d2[n2]=dis[i];
}
}
if (n1*n2<k)
{
printf("Stupid Mike\n");
fclose(stdin);
fclose(stdout);
return 0;
}
sort(d1+1,d1+n1+1);
sort(d2+1,d2+n2+1);
for (i=1;i<=n1;i++)
{
num++;
d[num].val=d1[i]+d2[1];
d[num].idi=i;
d[num].idj=1;
up(num);
}
for (i=1;i<k;i++)
{
ans1=d[1].idi;
ans2=d[1].idj;
d[1].val=d[num].val;
d[1].idi=d[num].idi;
d[1].idj=d[num].idj;
num--;
down(1);
if (ans2+1<=n2)
{
num++;
d[num].val=d1[ans1]+d2[ans2+1];
d[num].idi=ans1;
d[num].idj=ans2+1;
up(num);
}
}
printf("%lld\n",d[1].val);
fclose(stdin);
fclose(stdout);
return 0;
}

【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行的更多相关文章

  1. 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列

    [NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...

  2. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  3. 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天

    [NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...

  4. 【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划

    [NOIP2015模拟11.4]JZOJ8月6日提高组T1 刷题计划 题目 题解 题意 有\(n\)道题,编号为1~\(n\) 给出\(m\)次操作 每次操作有3种类型 1 \(x\) 表示交了\(A ...

  5. JZOJ8月4日提高组反思

    JZOJ8月4日提高组反思 被一堆2018&2019&2020的巨佬暴打 又是愉快的爆0的一天呢 T1 看了看题 没想法 暴力走起 求个质因数呀,二分呀-- 然后就炸了 正解预处理加二 ...

  6. JZOJ8月10日提高组反思

    JZOJ8月10日提高组反思 T1 没想到怎么打 就去打暴力了 本来想拿个30不错了 结果\(AC\)了 话说回来,数据也挺小的 T2 不AC便爆0 就一个数据点 给不给打暴力的人活了 正解是状压DP ...

  7. JZOJ8月15日提高组反思——2020年暑假终结篇

    JZOJ8月15日提高组反思--2020年暑假终结篇 T1 仙人掌最短路 抱歉我只会最短路 仙人掌是啥? 听说是缩点+\(LCA\) 最短路30 T2 直接暴力计算 正解\(DP\) \(amazin ...

  8. JZOJ8月5日提高组反思

    JZOJ8月5日提高组反思 再次炸了 虽然不是爆0 但也没差多少-- T1 想的DP 然后就打了 一开始是只能拿60的 后来想到了用前缀和优化 然后打完交了 最后一分钟测了一下空间 爆了 就赶紧把数组 ...

  9. JZOJ8月10日提高组T2 Fix

    JZOJ8月10日提高组T2 Fix 题目 Description There are a few points on a plane, and some are fixed on the plane ...

随机推荐

  1. [Luogu P1119] 灾后重建 (floyd)

    题面 传送门:https://www.luogu.org/problemnew/show/P1119 Solution 这题的思想很巧妙. 首先,我们可以考虑一下最暴力的做法,对每个时刻的所有点都求一 ...

  2. 01_cifsd 高性能网络共享服务

    01_cifsd 高性能网络共享服务 1.简介 cifsd 是一款高性能I/O网络文件共享服务, 通过一种与kernel直接交互的方式实现, github简介:https://github.com/n ...

  3. css 两边宽度固定中间自适应宽度

    #content_left{   //左 width:73px; height:100px; vertical-align:middle; margin-right:-100px; float:lef ...

  4. php 导出excel 10万数据

    php导出excel 10万数据(此代码主要测试用) 在工作当中要对一些基本信息和其他信息导出 起初信息比较小无所谓.... 但当信息超出65535的时候 发现点问题了 超出了 而且 反应速度很慢 实 ...

  5. MFC的大致讲解

    现在使用MFC框架的人越来越少了,现在大家都在用QT框架来写,对应初学者就我感觉来说,MFC真的是一个很好的框架,现在在工业方面使用的几乎都是MFC,所以以后就业想要往工业方面找C++工作,可以好好看 ...

  6. Socket 套接字的系统调用

    socket 结构 /** * struct socket - general BSD socket * @state: socket state (%SS_CONNECTED, etc) * @ty ...

  7. setPriority()优先级

    1 . 优先级表示重要程度或者紧急程度.但是能不能抢到资源也是不一定.2 . 分配优先级:反映线程的重要或紧急程度线程的优先级用1-10 表示,1的优先级最低,10的优先级最高,默认值是5 packa ...

  8. 微软面试题: LeetCode 4. 寻找两个正序数组的中位数 hard 出现次数:3

    题目描述: 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的中位数. 进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决 ...

  9. 应届生应聘阿里,腾讯,美团90%会被问到的Netty面试题!史上最全系列!

    1.BIO.NIO 和 AIO 的区别? BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理.线程开销大.伪异步 IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源 ...

  10. Markdown特点

    前言 以前经常在 gitHub 中看到 .md 格式的文件,一直没有注意,也不明白为什么文本文档的后缀不是 .txt ,后来无意中看到了 Markdown,看到了用这个东西写得一些web界面等特别的规 ...