【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行
【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 旅行的更多相关文章
- 【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\)个元素的 ...
- 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃
[NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...
- 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天
[NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...
- 【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划
[NOIP2015模拟11.4]JZOJ8月6日提高组T1 刷题计划 题目 题解 题意 有\(n\)道题,编号为1~\(n\) 给出\(m\)次操作 每次操作有3种类型 1 \(x\) 表示交了\(A ...
- JZOJ8月4日提高组反思
JZOJ8月4日提高组反思 被一堆2018&2019&2020的巨佬暴打 又是愉快的爆0的一天呢 T1 看了看题 没想法 暴力走起 求个质因数呀,二分呀-- 然后就炸了 正解预处理加二 ...
- JZOJ8月10日提高组反思
JZOJ8月10日提高组反思 T1 没想到怎么打 就去打暴力了 本来想拿个30不错了 结果\(AC\)了 话说回来,数据也挺小的 T2 不AC便爆0 就一个数据点 给不给打暴力的人活了 正解是状压DP ...
- JZOJ8月15日提高组反思——2020年暑假终结篇
JZOJ8月15日提高组反思--2020年暑假终结篇 T1 仙人掌最短路 抱歉我只会最短路 仙人掌是啥? 听说是缩点+\(LCA\) 最短路30 T2 直接暴力计算 正解\(DP\) \(amazin ...
- JZOJ8月5日提高组反思
JZOJ8月5日提高组反思 再次炸了 虽然不是爆0 但也没差多少-- T1 想的DP 然后就打了 一开始是只能拿60的 后来想到了用前缀和优化 然后打完交了 最后一分钟测了一下空间 爆了 就赶紧把数组 ...
- JZOJ8月10日提高组T2 Fix
JZOJ8月10日提高组T2 Fix 题目 Description There are a few points on a plane, and some are fixed on the plane ...
随机推荐
- MarkDown及Typora文本编辑器
文章介绍主要介绍MarkDown语法和与之能够配套使用的文本编辑器Typora的下载使用 1. MarkDown简介 MarkDown是一种纯文本标记语言,其书写与txt.word文档类似: 所有网站 ...
- Docker(2)- Centos 7.x 下安装 Docker
如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 前言 虚拟机安装 centos ...
- 微信小程序开发实战(云开发)--资产管理工具
添加首页 menu页面 截图展示 menu.js源码 // pages/menu/menu.js Page({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听 ...
- .Net Newtonsoft.Json 转json时将枚举转为字符串
1:非列表类型枚举 [JsonConverter(typeof(StringEnumConverter))] public SubjectTypeEnum subject_type { get; se ...
- C# 中的数字分隔符 _
编写 C# 代码时,我们时常会用到很大的数字,例如下面定义的变量: const long loops = 50000000000; 您能快速读出这是多少吗?是不是还是会有很多人把光标定位到最后一位,然 ...
- Go语言内存分配(简述 转)
在Go语言里,从内存的分配到不再使用后内存的回收等等这些内存管理工作都是由Go在底层完成的.虽然开发者在写代码时不必过度关心内存从分配到回收这个过程,但是Go的内存分配策略里有不少有意思的设计,通过了 ...
- uboot——初始化阶段
start.S |-------------设置cpu状态 |--------------开cache |--------------获得启动方式 |------------------------- ...
- 【java从入门到精通】day-06-基本运算符-自增自减运算符
1.运算符 java语言支持如下运算符: 算术运算符:+,-,*,/,%,++,-- 赋值运算符:= 关系运算符:>,<,>=,<=,==,!=,instanceof 逻辑运算 ...
- 面经手册 · 第18篇《AQS 共享锁,Semaphore、CountDownLatch,听说数据库连接池可以用到!》
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- 实验吧[WEB]——what a fuck!这是什么鬼东西?
解题链接:http://ctf5.shiyanbar.com/DUTCTF/1.html 原题链接:http://www.shiyanbar.com/ctf/56 解题必看: 的jother编码定义: ...