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. Django--入门篇:下载与项目生成

    django作为python web应用开发最火的框架,没有之一,今天就给大家介绍django的一些入门知识. 我们选择pycharm工具,首先得要有django. 1.下载django --pip ...

  2. TED - How To Get Better At The Things You Care About

    TED01 - How To Get Better At The Things You Care About 昨天我发布了攻克英语口语的宣言,今天就行动.TED是我们学习口语的好地方,本着学以致用的原 ...

  3. 【Swift】 iOS开发容易产生Bug的地方

    1.隐藏navigationBar(尤其是多级隐藏) 2.共用collectionView或tableView 3.继承关系下,注意覆写父类时的super方法的调用 4.关于权限的问题(相机权限,相册 ...

  4. android 检查软件是否有更新版本

    import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import com.yuxin.m ...

  5. android 自定义ScrollView实现背景图片伸缩(阻尼效果)

    android 自定义ScrollView实现强调内容背景图片伸缩(仿多米,qq空间背景的刷新) 看到一篇文章,自己更改了一下bug: 原文地址:http://www.aiuxian.com/arti ...

  6. 2017 国庆湖南 Day6

    期望得分:100+100+60=260 实际得分:100+85+0=185 二分最后一条相交线段的位置 #include<cstdio> #include<iostream> ...

  7. raid5 阵列硬盘离线数据恢复成功案例

    数据恢复故障描述: 某研究院 DELL 磁盘阵列崩溃,内置15块1TB硬盘搭建的RAID5阵列.一开始有一块硬盘离线,在更换新硬盘进行同步的过程中,第二块磁盘指示灯报警,同步失败,阵列无法正常工作. ...

  8. EasyUi中对话框。

    html页面代码: <head id="Head1" runat="server"> <meta http-equiv="Conte ...

  9. LeetCode & Q268-Missing Number-Easy

    Array Math Bit Manipulation Description: Given an array containing n distinct numbers taken from 0, ...

  10. LeetCode & Q88-Merge Sorted Array-Easy

    Array Two Pointers Description: Given two sorted integer arrays nums1 and nums2, merge nums2 into nu ...