#P0044. [FJOI2014] 最短路径树问题

题目描述
给一个包含 nn 个点,mm 条边的无向连通图。从顶点 11出发,往其余所有点分别走一次并返回。

往某一个点走时,选择总长度最短的路径走。若有多条长度最短的路径,则选择经过的顶点序列字典序最小的那条路径(如路径 AA 为 1,32,111,32,11,路径 BB 为 1,3,2,111,3,2,11,路径 BB 字典序较小。注意是序列的字典序的最小,而非路径中节点编号相连的字符串字典序最小)。到达该点后按原路返回,然后往其他点走,直到所有点都走过。

可以知道,经过的边会构成一棵最短路径树。请问,在这棵最短路径树上,最长的包含 kk 个点的简单路径长度为多长?长度为该最长长度的不同路径有多少条?

这里的简单路径是指:对于一个点最多只经过一次的路径。不同路径是指路径两端端点至少有一个不同,点 AA 到点 BB 的路径和点 BB 到点 AA 视为同一条路径。

输入格式
第一行输入三个正整数 n,m,kn,m,k,表示有 nn 个点 mm 条边,要求的路径需要经过 kk 个点。 接下来输入 mm 行,每行三个正整数 A_i,B_i,C_iA
i

,B
i

,C
i

(1\leq A_i,B_i\leq n,1\leq C_i\leq 100001≤A
i

,B
i

≤n,1≤C
i

≤10000),表示 A_iA
i

和 B_iB
i

间有一条长度为 C_iC
i

的边。数据保证输入的是连通的无向图。

输出格式
输出一行两个整数,以一个空格隔开,第一个整数表示包含 kk 个点的路径最长为多长,第二个整数表示这样的不同的最长路径有多少条。

输入数据 1
6 6 4
1 2 1
2 3 1
3 4 1
2 5 1
3 6 1
5 6 1
输出数据 1
3 4
数据范围与提示
对于所有数据,n\leq 30000,m\leq 60000n≤30000,m≤60000,2\leq k\leq n2≤k≤n。

数据保证最短路径树上至少存在一条长度为 kk 的路径。

变更记录
因本题原题与P0087合并果子重复

本题更换为[FJOI2014] 最短路径树问题

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
const int N=3e4+10;
struct Edge
{
    int v,w;
    bool friend operator <(Edge n1,Edge n2){return n1.v<n2.v;}
}t;
std::vector <Edge> e[N],e0[N];
int n,m,k;
const int inf=0x3f3f3f3f;
#define P std::pair <int,int>
std::priority_queue <P,std::vector <P >,std::greater <P> > q;
int dis[N],used[N];
int head[N],to[N<<1],edge[N<<1],Next[N<<1],cnt;
void add(int u,int v,int w)
{
    to[++cnt]=v,Next[cnt]=head[u],edge[cnt]=w,head[u]=cnt;
}
void disj()
{
    memset(dis,0x3f,sizeof(dis));
    q.push(std::make_pair(dis[1]=0,1));
    while(!q.empty())
    {
        int u=q.top().second;
        q.pop();
        if(used[u]) continue;
        used[u]=1;
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i].v,w=e[u][i].w;
            if(dis[v]>dis[u]+w)
            {
                dis[v]=dis[u]+w;
                q.push(std::make_pair(dis[v],v));
            }
        }
    }
    memset(used,0,sizeof(used));
}
void dfsbuild(int now)
{
    used[now]=1;
    for(int i=0;i<e0[now].size();i++)
    {
        int v=e0[now][i].v,w=e0[now][i].w;
        if(!used[v])
        {
            add(now,v,w);
            add(v,now,w);
            dfsbuild(v);
        }
    }
}
void build()
{
    for(int u=1;u<=n;u++)
    {
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i].v,w=e[u][i].w;
            if(dis[v]==dis[u]+w)
                t={v,w},e0[u].push_back(t);
        }
        std::sort(e0[u].begin(),e0[u].end());
    }
    dfsbuild(1);
}
int ans,siz[N],rt,mi,mxlen[N],mx,del[N],td[N],tmxlen[N],scnt[N],tcnt[N];
int max(int x,int y){return x>y?x:y;}
void dfsroot(int now,int fa,int sz)
{
    siz[now]=1;
    int mx0=0;
    for(int i=head[now];i;i=Next[i])
    {
        int v=to[i];
        if(v==fa||del[v]) continue;
        dfsroot(v,now,sz);
        mx0=max(mx0,siz[v]);
        siz[now]+=siz[v];
    }
    mx0=max(mx0,sz-siz[now]);
    if(mx0<mi) mi=mx0,rt=now;
}
void dfs(int now,int fa,int dis,int dep)
{
    if(dep>k) return;
    if(mx<dis+mxlen[k-dep])
    {
        mx=dis+mxlen[k-dep];
        ans=scnt[k-dep];
    }
    else if(mx==dis+mxlen[k-dep])
        ans+=scnt[k-dep];
    for(int i=head[now];i;i=Next[i])
    {
        int v=to[i];
        if(v==fa||del[v]) continue;
        dfs(v,now,dis+edge[i],dep+1);
    }
    if(tmxlen[dep]<dis)
    {
        tmxlen[dep]=dis;
        tcnt[dep]=1;
    }
    else if(tmxlen[dep]==dis)
        tcnt[dep]++;
}
void dfz(int now,int sz)
{
    mi=1<<30;
    dfsroot(now,0,sz);
    now=rt;
    del[now]=1;
    for(int i=head[now];i;i=Next[i])
    {
        int v=to[i];
        if(del[v]) continue;
        dfs(v,now,edge[i],1);
        for(int j=1;tmxlen[j]!=-inf;j++)
        {
            if(tmxlen[j]>mxlen[j])
            {
                scnt[j]=tcnt[j];
                mxlen[j]=tmxlen[j];
            }
            else if(tmxlen[j]==mxlen[j])
                scnt[j]+=tcnt[j];
            tcnt[j]=0,tmxlen[j]=-inf;
        }
    }
    if(mx<mxlen[k]) ans=scnt[k],mx=mxlen[k];
    else if(mx==mxlen[k]) ans+=scnt[k];
    for(int i=1;mxlen[i]!=-inf;i++) mxlen[i]=-inf;
    for(int i=head[now];i;i=Next[i])
        if(!del[to[i]])
            dfz(to[i],siz[to[i]]);
}
int main()
{
    //freopen("data.in","r",stdin);
    //freopen("wr.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(int u,v,w,i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        t={v,w};
        e[u].push_back(t);
        t={u,w};
        e[v].push_back(t);
    }
    disj();
    build();
    --k;
    for(int i=0;i<=k+1;i++)
        tmxlen[i]=mxlen[i]=-inf;
    dfz(1,n);
    printf("%d %d\n",mx,ans);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/297053.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue CLI组件通信

目录 一、组件通信简介1.什么是组件通信&#xff1f;2.组件之间如何通信3.组件关系分类4.通信解决方案5.父子通信流程6.父向子通信代码示例7.子向父通信代码示例8.总结 二、props1.Props 定义2.Props 作用3.特点4.代码演示 三、props校验1.思考2.作用3.语法4.代码演示 四、prop…

科锐16位汇编学习笔记 03 汇编指令

指令种类 数据传送指令算数运算类指令位操作类指令串操作类指令控制转移类指令处理器控制类指令 数据传送类指令 传送类指令不影响标志位&#xff0c;**除了标志位传送指令外。** 传送指令MOV&#xff08;move&#xff09; 说明 ​ 把一个字节或字的操作数从源地址传送至…

swift ——多行文字前面内容省略

首先来说一说ios中的 lineBreakModelineBreakMode : 设置文字过长时的显示截断样式 可选值如下 byWordWrapping &#xff1a; 以单词为单位换行&#xff0c;以单词为单位截断。byCharWrapping &#xff1a;以字符为单位换行&#xff0c;以字符为单位截断。byClipping &#x…

Linux进程管理、ps命令、kill命令

每一个程序在运行的时候都会被操作系统注册为系统中的一个进程 补充一下操作系统的内容&#xff1a; 进程实体&#xff08;又称进程映像&#xff09;&#xff1a;程序段、相关数据段、PCB三部分构成 进程是进程实体的运行过程&#xff0c;是系统进行资源分配的一个独立单位 …

关于时间格式yyyy-M-d或yyyy-MM-d到yyyy-MM-dd的转换

工作时遇到前端传的时间格式是"2023-12-3 17:41:52"&#xff0c;和"2023-1-1 17:41:52"但是我想要的是"2023-12-03 17:41:52"和"2023-01-01 17:41:52"。下面给大家分享几个解决方法 方法一&#xff1a; 找前端&#xff01;让他改&…

关于《码农翻身》一书的读后感以及自己的一些拙见汇总

书籍名称 《码农翻身》 | 刘欣&#xff08;码农翻身&#xff09; 著 | 文章将以问答的形式进行叙述 1.是从什么渠道接触到《码农翻身》的 一个工作日的下午&#xff0c;手上的任务基本结束&#xff0c;翻了翻桌上的书和笔记之类的&#xff0c;同事见我在看书&#xff0c;于是向…

用opencv的DNN模块做Yolov5目标检测(纯干货,源码已上传Github)

最近在微信公众号里看到多篇讲解yolov5在openvino部署做目标检测文章&#xff0c;但是没看到过用opencv的dnn模块做yolov5目标检测的。于是&#xff0c;我就想着编写一套用opencv的dnn模块做yolov5目标检测的程序。在编写这套程序时&#xff0c;遇到的bug和解决办法&#xff0c…

Mac启动时候出现禁止符号

Mac启动时候出现禁止符号 启动时候出现禁止符号,意味着 选定的启动磁盘 包含 Mac 操作系统&#xff0c;但它不是 您的 Mac 可以使用的 macOS 。您应该在这个磁盘上 重新安装 macOS 。 可以尝试以下苹果提供的方法&#xff1a; Mac启动时候出现禁止符号 不要轻易抹除磁盘&am…

2023 最火的是什么? 超维计算 + 神经网络

从chatgpt开始&#xff0c;人工智能进步的步伐似乎势不可挡&#xff0c;但支撑这些程序的人工神经网络遇到了一些重大限制&#xff0c;其他的很难推理但是人类的大脑能够通过类比进行推理&#xff0c;当我们看到新事物时&#xff0c;我们不必生长新的神经元&#xff0c;我们可以…

【python】Python 3.11不支持Tix库

Tix库主要用于扩展Tkinter&#xff0c;但是Python 3.11 Tkinter已经不再支持Tix库。Tix模块提供了一些额外的部件和功能&#xff0c;但现在这些功能已经整合到了Tkinter库中。 一、如果在Python 3.11中想要使用Tix库&#xff0c;但发现它不再被内置支持&#xff0c;可以尝试以…

QCharView使用

QChart是 QGraphicsWidget的子类。 QCharView是QGraphicsView的子类 QCharView概念:title、系列、图标Chart、视图 说明: 需要添加Qt组件charts 在使用QChart或者QChartView之前需要添加宏定义QT_CHARTS_USE_NAMESPACE &#xff08;其实是使用了命名空间&#xff09;&#xff…

KVM虚拟化技术

在当今的云计算时代&#xff0c;虚拟化技术已经成为了企业和个人用户的首选。而在众多虚拟化技术中&#xff0c;KVM&#xff08;Kernel-based Virtual Machine&#xff09;虚拟化技术因其高性能、低成本和灵活性而备受青睐。本文将介绍KVM虚拟化技术的原理、特点以及应用场景。…

CDMP考试解析:从报名到成功不走弯路

❤️CDMP数据管理专业认证是由DAMA国际于2004推出&#xff0c;是一项涵盖学历教育、工作经验和专业知识考试在内的综合资格认证&#xff0c;也是目前全球wei一数据管理方面权威性认证。 &#x1f4b0;考试费用&#xff1a;CDMP的考试费用约为每科2500元。 其他可能的费用&#…

【web】Springboot3 集成 Swagger3

文章目录 Maven 依赖配置类&#xff08;可选&#xff09;访问示例 Maven 依赖 <!--swagger3--> <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.0.2</v…

什么是谐波减速机?日本Harmonic哈默纳科谐波减速机有哪些优点?

一、什么是谐波减速机&#xff1f; 谐波减速装置最早期被叫做“strain wave gearing”&#xff0c;直译过来为“应变波齿轮”。其后被HarmonicDrive Systems 公司大规模商业实用化后&#xff0c;经过二次翻译后&#xff0c;中文名称才将其称为“谐波齿轮传动”。 谐波减速机是…

Ubuntu18 安装chatglm2-6b

记了下Ubuntu18 上安装chatglm2-6遇到的问题。 环境&#xff1a;Ubuntu18.04 V100(显卡) nvcc 11.6 显卡驱动cudacudnnaniconda chatglm6b 的安装 网上有很多&#xff0c; 不记录 了。 chatglm2-6b 我从别的地方拷贝的&#xff0c; 模型也包含了。 遇到的问题&#xf…

C++补充内容--语法篇

这里写目录标题 语法其他语法函数的存储类函数参数默认值格式默认参数位置重载函数的默认参数 指针名与正常指针的自增自减以及解引用与的优先级问题指针的赋值、加减数字、加减指针二维数组中的一些指针辨析输出调用字符指针时 会将该指针以及之后的元素全部输出二维数组未完全…

【Docker】配置阿里云镜像加速器

默认情况下&#xff0c;将来从docker hub &#xff08;https://hub.docker.com )上下载镜像太慢&#xff0c;所以一般配置镜像加速器。 没有账号的注册一个账号并登录 登录之后点击控制台 查看 cat /etc/docker/daemon.json

网络名称解读 -入门5

WAN: Wide Area Network(跨区域&#xff09;&#xff0c;LAN&#xff1a; Local Area NetworkWAN MAC&#xff0c; 用来连接上级网络&#xff0c; LAN MAC&#xff0c; 用于内部网路。 LAN & WAN 3.1&#xff0c;LAN表示子网&#xff0c;通过掩码来筛选子网内主机数量&…

多线程和JVM

一&#xff0c;多线程实现的四种方式 1. 实现Runnable接口 普通实现&#xff1a; public class MyRunnable implements Runnable {Overridepublic void run() {System.out.println("线程执行中...");} }public class Main {public static void main(String[] arg…
最新文章