【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. python的各版本的不同

    Python的版本主要分为 2.× . 3.× 两个系列. Python3计划每年发布一个新的子版本,一次只增加一两种新语法. 使用时当然选择越新的Python版本越好,版本越老的代码越难维护. 维护 ...

  2. ESP8266交叉编译环境变量设置

    在build目录下执行sudo cp -r xtensa-lx106-elf /opt 修改xtensa-lx106-elf目录权限:这一步非常重要,否则在后续编译中很容易出现没有权限问题:sudo ...

  3. 【转】linux自测题

    一.填空题: 1. 在Linux系统中,以 文件 方式访问设备. 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 来标 ...

  4. JavaScript兼容性总结一点点

    JavaScript 不同浏览器之间的差异还是很大,所以js库才这么有需求,需要解决各种兼容性问题. 其实反过来,既然存在js库能解决这些兼容性问题,说明底层大部分功能还是相通的. 首先想到的是事件模 ...

  5. BATJTMD,大厂招聘,都招什么样Java程序员?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 Java学到什么程度可以找工作? 最近总看到类似这样的问题,也有一些工作3年左右的小 ...

  6. Ceph根据Crush位置读取数据

    前言 在ceph研发群里面看到一个cepher在问关于怎么读取ceph的副本的问题,这个功能应该在2012年的时候,我们公司的研发就修改了代码去实现这个功能,只是当时的硬件条件所限,以及本身的稳定性问 ...

  7. Spring之事务源码

    对@Transactional注解的类进行动态代理 同前文<Spring AOP源码分析>中分析动态代理入口一样,都是在initializeBean时执行. Object exposedO ...

  8. C函数 printf 拼接字符串

    C函数 printf 拼接字符串 从前学C语言,最常用的函数可能就是 printf 了,但是往往是这样: printf(年龄是:"%d",a); 由于不懂得怎么拼接字符串,有时候只 ...

  9. 我要进大厂之大数据ZooKeeper知识点(2)

    01 我们一起学大数据 接下来是大数据ZooKeeper的比较偏架构的部分,会有一点难度,老刘也花了好长时间理解和背下来,希望对想学大数据的同学有帮助,也特别希望能够得到大佬的批评和指点. 02 知识 ...

  10. Dnscat2实现DNS隐蔽隧道反弹Shell

    DNS介绍 DNS是域名系统(Domain Name System)的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被 ...