Description

给一个包含n个点,m条边的无向连通图。从顶点1出发,往其余所有点分别走一次并返回。
往某一个点走时,选择总长度最短的路径走。若有多条长度最短的路径,则选择经过的顶点序列字典序最小的那条路径(如路径A为1,32,11,路径B为1,3,2,11,路径B字典序较小。注意是序列的字典序的最小,而非路径中节点编号相连的字符串字典序最小)。到达该点后按原路返回,然后往其他点走,直到所有点都走过。
可以知道,经过的边会构成一棵最短路径树。请问,在这棵最短路径树上,最长的包含K个点的简单路径长度为多长?长度为该最长长度的不同路径有多少条?
这里的简单路径是指:对于一个点最多只经过一次的路径。不同路径是指路径两端端点至少有一个不同,点A到点B的路径和点B到点A视为同一条路径。

Input

第一行输入三个正整数n,m,K,表示有n个点m条边,要求的路径需要经过K个点。接下来输入m行,每行三个正整数Ai,Bi,Ci(1<=Ai,Bi<=n,1<=Ci<=10000),表示Ai和Bi间有一条长度为Ci的边。数据保证输入的是连通的无向图。
 
 

Output

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

Sample Input

6 6 4
1 2 1
2 3 1
3 4 1
2 5 1
3 6 1
5 6 1

Sample Output

3 4

HINT

对于所有数据n<=30000,m<=60000,2<=K<=n。
数据保证最短路径树上至少存在一条长度为K的路径
2016.12.7新加数据一组by - wyx-150137

首先求字典序最小的最短路树,考虑将边拆成两条单向边,然后按终点从大到小排序,按序插入链式前向星中,保证找到的第一条最短路就是字典序最小的。

点分就比较裸了,记深度为 $i$ 时最大的路径长度为 $sum_i$ ,长度为 $sum_i$ ,且深度为 $i$ 的路径数为 $cnt_i$ 直接转移就好了。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct ZYYS
{
int u,v,d;
}E[];
struct Node
{
int next,to,d;
}edge[];
int num,head[],dist[],pre[],pred[];
int size[],maxsize[],minsize,root,w[],k,ans,dep_max,n,m,cnt,c[];
bool vis[];
bool cmp(ZYYS a,ZYYS b)
{
if (a.u==b.u) return a.v>b.v;
return a.u<b.u;
}
void add(int u,int v,int d)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
edge[num].d=d;
}
void SPFA()
{int i;
queue<int>Q;
memset(dist,/,sizeof(dist));
Q.push();
dist[]=;
while (Q.empty()==)
{
int u=Q.front();
Q.pop();
vis[u]=;
for (i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if (dist[v]>dist[u]+edge[i].d)
{
pre[v]=u;
pred[v]=edge[i].d;
dist[v]=dist[u]+edge[i].d;
if (vis[v]==)
{
vis[v]=;
Q.push(v);
}
}
}
}
}
void get_size(int x,int pa)
{int i;
size[x]=;
maxsize[x]=;
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa||vis[v]) continue;
get_size(v,x);
size[x]+=size[v];
maxsize[x]=max(maxsize[x],size[v]);
}
}
void get_root(int x,int pa,int r)
{int i;
maxsize[x]=max(size[r]-size[x],maxsize[x]);
if (maxsize[x]<minsize)
{
minsize=maxsize[x];
root=x;
}
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa||vis[v]) continue;
get_root(v,x,r);
}
}
void get_ans(int x,int pa,int dis,int dep)
{int i;
if (c[k--dep]&&w[k--dep]+dis==ans)
cnt+=c[k--dep];
else if (c[k--dep]&&ans<w[k--dep]+dis)
ans=w[k--dep]+dis,cnt=c[k--dep];
dep_max=max(dep_max,dep);
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa||vis[v]||dep==k-) continue;
get_ans(v,x,dis+edge[i].d,dep+);
}
}
void get_update(int x,int pa,int dis,int dep)
{int i;
if (dis>w[dep]) w[dep]=dis,c[dep]=;
else if (dis==w[dep]) c[dep]++;
dep_max=max(dep_max,dep);
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa||vis[v]||dep==k-) continue;
get_update(v,x,dis+edge[i].d,dep+);
}
}
void slove(int x)
{int i;
minsize=2e9;
get_size(x,);
get_root(x,,x);
vis[root]=;
dep_max=;
c[]=;
for (i=head[root];i;i=edge[i].next)
{
int v=edge[i].to;
if (vis[v]) continue;
get_ans(v,root,edge[i].d,);
get_update(v,root,edge[i].d,);
}
for (i=;i<=dep_max;i++)
w[i]=,c[i];
for (i=head[root];i;i=edge[i].next)
{
int v=edge[i].to;
if (vis[v]==)
slove(v);
}
}
int main()
{int i,u,v,d;
cin>>n>>m>>k;
for (i=;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&d);
E[*i-].u=u,E[*i-].v=v,E[*i-].d=d;
E[*i].u=v;E[*i].v=u,E[*i].d=d;
}
sort(E+,E+*m+,cmp);
for (i=;i<=*m;i++)
{
add(E[i].u,E[i].v,E[i].d);
}
SPFA();
memset(head,,sizeof(head));
num=;
for (i=;i<=n;i++)
add(i,pre[i],pred[i]),add(pre[i],i,pred[i]);
slove();
cout<<ans<<' '<<cnt<<endl;
}

[FJOI2014]最短路径树问题的更多相关文章

  1. [BZOJ4016][FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 试题描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长 ...

  2. bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)

    4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 426  Solved: 147[Submit][Stat ...

  3. BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治

    BZOJ_4016_[FJOI2014]最短路径树问题_最短路+点分治 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择 ...

  4. 【BZOJ4016】[FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...

  5. [FJOI2014]最短路径树问题 长链剖分

    [FJOI2014]最短路径树问题 LG传送门 B站传送门 长链剖分练手好题. 如果你还不会长链剖分的基本操作,可以看看我的总结. 这题本来出的很没水平,就是dijkstra(反正我是不用SPFA)的 ...

  6. [BZOJ4016][FJOI2014]最短路径树问题(dijkstra+点分治)

    4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 1796  Solved: 625[Submit][Sta ...

  7. 洛谷 [FJOI2014]最短路径树问题 解题报告

    [FJOI2014]最短路径树问题 题目描述 给一个包含\(n\)个点,\(m\)条边的无向连通图.从顶点\(1\)出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多 ...

  8. 【BZOJ4016】[FJOI2014]最短路径树问题 最短路径树+点分治

    [BZOJ4016][FJOI2014]最短路径树问题 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径 ...

  9. 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)

    [BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...

  10. bzoj 4016: [FJOI2014]最短路径树问题

    bzoj4016 最短路路径问题 Time Limit: 5 Sec Memory Limit: 512 MB Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点 ...

随机推荐

  1. iPhone的App嵌入html页面问题

    测试环境:iPhone ios 11.0.3 问题:iPhone App嵌入HTML页面,页面拉动到底部时,手势从屏幕底部边缘开始往上拉动,页面出现白色图层,且html页面一屏外的会卡住,无法滚动,需 ...

  2. 『开源重编译』System.Data.SQLite.dll 自适应 x86 x64 AnyCPU 重编译

    背景: > System.Data.SQLite.dll 程序集 不能良好的支持 AngCPU 格式 System.Data.SQLite.dll 在 适应 x86 和 x64 有三个方案: & ...

  3. Leetcode 24——Swap Nodes in Pairs

    Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2-& ...

  4. C语言程序设计(基础)- 第7周作业(新)

    要求一(25经验值) 完成PTA中题目集名为<usth-C语言基础-第七周作业>和<usth-C语言基础-12周PTA作业>中的所有题目. 注意1:<usth-C语言基础 ...

  5. 第201621123043 《Java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车. 2.1 简述如何 ...

  6. 2017-2018-1 我爱学Java 第四五周 作业

    <打地鼠>Android游戏--需求规格说明书 工作流程 组员分工及工作量比例 <需求规格说明书>的码云链接 总结与反思 参考资料 工作流程 小组成员预先参考蓝墨云班课第八周中 ...

  7. Scrum 冲刺 第七日

    Scrum 冲刺 第七日 站立式会议 燃尽图 今日任务安排 项目发布说明 站立式会议 返回目录 燃尽图 返回目录 今日任务安排 返回目录 项目发布说明 本版本的新功能 不只是简单打地鼠,还有一些不能打 ...

  8. 《高级软件测试》11.16.Jira使用说明的撰写和操作视频的录制

    今日任务完成情况如下: 小王:完成了测试管理工具jira的使用手册中,基本情况介绍.下载安装部分的撰写工作:小高:参考官方手册,结合自己的实际使用体会,对jira的基本组成及其工作流程进行了介绍:小陈 ...

  9. NOIP2012 提高组 Day 2

    http://www.cogs.pro/cogs/page/page.php?aid=16 期望得分:100+100+0=0 实际得分:100+20+0=120 T2线段树标记下传出错 T1 同余方程 ...

  10. Mego开发文档 - 基本保存操作

    基本保存操作 在Mego中没有更改跟踪,也就是说所有的新增.更新及删除都需要开发者自行判断.Mego会最为实际的将各个数据操作提交给数据库并执行. 添加数据 using (var db = new O ...