博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 [FJOI2014]最短路径树问题 解题报告
阅读量:5294 次
发布时间:2019-06-14

本文共 2212 字,大约阅读时间需要 7 分钟。

[FJOI2014]最短路径树问题

题目描述

给一个包含\(n\)个点,\(m\)条边的无向连通图。从顶点\(1\)出发,往其余所有点分别走一次并返回。

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

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

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

输入输出格式

输入格式:

第一行输入三个正整数\(n\),\(m\),\(K\),表示有\(n\)个点\(m\)条边,要求的路径需要经过\(K\)个点。

接下来输入\(m\)行,每行三个正整数\(A_i,B_i,C_i(1\le A_i,B_i\le n,1 \le C_i\le10000)\),表示\(A_i\)\(B_i\)间有一条长度为\(C_i\)的边。

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

输出格式:

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

说明

对于所有数据\(n\le30000,m\le60000\)\(2\le K\le n\)

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


Solution

第二自然段的题意我现在都没弄懂。

用我的理解就是先保证最短路,然后保证连边的编号的字典序是最小的。

这个可以先把最短路图跑出来,然后对每个点的出边排序,从\(1\)开始跑\(DFS\),边跑边连边

然后就是淀粉质了。

吐槽题意+强行拼题+写起来不爽(不是为了了解一下最短路树我才不写呢)

复杂度\(O(nlogn)\)


Code:

#include 
#include
#include
#include
#include
const int N=3e4+10;struct Edge{ int v,w; bool friend operator <(Edge n1,Edge n2){return n1.v
e[N],e0[N];int n,m,k;const int inf=0x3f3f3f3f;#define P std::pair
std::priority_queue

,std::greater

> 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

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
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
k) return; if(mx
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


2018.10.22

转载于:https://www.cnblogs.com/butterflydew/p/9829328.html

你可能感兴趣的文章
14.typescript-类与接口
查看>>
js学习(精华帖)
查看>>
和小哥哥一起刷洛谷(1)
查看>>
分享squid缓存服务器配置-之conf配置文件的详细介绍
查看>>
jQuery教程详解(一)
查看>>
jquery对id中含有特殊字符的转义处理
查看>>
DP学习之路(1) 01背包
查看>>
获取元素样式信息于三中获取方式的区别
查看>>
测试主要环节
查看>>
08-17工作总结
查看>>
遇麻烦,Win7+Ubuntu12.10+Archlinux12.10 +grub
查看>>
基本高精度模板
查看>>
SqlBulkCopy大批量导入数据
查看>>
Windows Workflow Foundation 入门
查看>>
chrome(谷歌浏览器)“无法从该网站添加应用、扩展程序和用户脚本”问题
查看>>
HTTP协议 (四) 缓存
查看>>
python学习之random
查看>>
使用onclick跳转到其他页面/跳转到指定url
查看>>
【转载】测试计划模板
查看>>
pandas 修改指定列中所有内容
查看>>