题目大概要先求一张边有权的图的根为1的最短路径树,要满足根到各点路径序列的字典序最小;然后求这棵最短路径树包含k个结点的最长路径的长度和个数。

首先先构造出这棵字典序最小的最短路径树。。好吧,我太傻逼了,不会。。保证邻接表存储邻接点有序的前提下,就能按字典序DFS一遍,在O(N+E)的时间复杂度上构造出来了。

然后就是统计路径最长长度和方案数,树上路径问题当然就是树分治了。

不多谈。。%¥……¥%……¥……连续写了200多行然后一直出数据调了2个多小时才AC。。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 33333
#define MAXM 66666*2 struct Edge{
int v,w,next;
}edge[MAXM];
int NE,head[MAXN];
void addEdge(int u,int v,int w){
edge[NE].v=v; edge[NE].w=w;
edge[NE].next=head[u]; head[u]=NE++;
} int d[MAXN];
bool vis[MAXN];
void SPFA(int n){
for(int i=; i<=n; ++i){
d[i]=INF; vis[i]=;
}
d[]=; vis[]=;
queue<int> que;
que.push();
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(d[v]>d[u]+edge[i].w){
d[v]=d[u]+edge[i].w;
if(!vis[v]){
vis[v]=;
que.push(v);
}
}
}
vis[u]=;
}
} struct Node{
int u,v,w;
bool operator<(const Node &nd)const{
if(u==nd.u) return nd.v<v;
return u<nd.u;
}
}node[MAXM];
int cnt; void dfs(int u){
vis[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || d[u]+edge[i].w!=d[v]) continue;
node[cnt].u=u; node[cnt].v=v; node[cnt].w=edge[i].w;
++cnt;
dfs(v);
}
} int size[MAXN];
void getsize(int u,int fa){
size[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || v==fa) continue;
getsize(v,u);
size[u]+=size[v];
}
}
int mini,cen;
void getcen(int u,int fa,int &tot){
int res=tot-size[u];
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || v==fa) continue;
res=max(res,size[v]);
getcen(v,u,tot);
}
if(res<mini){
mini=res;
cen=u;
}
}
int getcen(int u){
getsize(u,u);
mini=INF;
getcen(u,u,size[u]);
return cen;
} int k;
int a_val[MAXN],a_cnt[MAXN],a_rec[MAXN],an,b_val[MAXN],b_cnt[MAXN],b_rec[MAXN],bn;
bool tag[MAXN];
int ans_val,ans_cnt;
void conqur_dfs(int u,int fa,int val,int tot){
if(b_val[tot]<val){
b_val[tot]=val;
b_cnt[tot]=;
if(!tag[tot]){
tag[tot]=;
b_rec[bn++]=tot;
}
}else if(b_val[tot]==val){
++b_cnt[tot];
}
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v] || v==fa) continue;
conqur_dfs(v,u,val+edge[i].w,tot+);
}
}
void conqur(int u){
an=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
bn=;
conqur_dfs(v,v,edge[i].w,);
for(int j=; j<bn; ++j){
if(b_rec[j]==k-){
if(b_val[b_rec[j]]>ans_val){
ans_val=b_val[b_rec[j]];
ans_cnt=b_cnt[b_rec[j]];
}else if(b_val[b_rec[j]]==ans_val){
ans_cnt+=b_cnt[b_rec[j]];
}
}else if(b_rec[j]<k-){
int tmp=k--b_rec[j];
if(a_cnt[tmp]==) continue;
if(b_val[b_rec[j]]+a_val[tmp]>ans_val){
ans_val=b_val[b_rec[j]]+a_val[tmp];
ans_cnt=b_cnt[b_rec[j]]*a_cnt[tmp];
}else if(b_val[b_rec[j]]+a_val[tmp]==ans_val){
ans_cnt+=b_cnt[b_rec[j]]*a_cnt[tmp];
}
}
}
for(int j=; j<bn; ++j){
int tmp=b_rec[j];
tag[tmp]=;
a_rec[an++]=tmp;
if(a_val[tmp]<b_val[tmp]){
a_val[tmp]=b_val[tmp];
a_cnt[tmp]=b_cnt[tmp];
}else if(a_val[tmp]==b_val[tmp]){
a_cnt[tmp]+=b_cnt[tmp];
}
b_val[tmp]=;
b_cnt[tmp]=;
}
}
for(int i=; i<an; ++i){
a_val[a_rec[i]]=;
a_cnt[a_rec[i]]=;
}
} void divide(int u){
u=getcen(u);
vis[u]=;
conqur(u);
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
divide(v);
}
} int main(){
int t,n,m,a,b,c;
scanf("%d",&t);
while(t--){
NE=;
memset(head,-,sizeof(head));
scanf("%d%d%d",&n,&m,&k);
for(int i=; i<m; ++i){
scanf("%d%d%d",&a,&b,&c);
node[i<<].u=a; node[i<<].v=b; node[i<<].w=c;
node[i<<|].u=b; node[i<<|].v=a; node[i<<|].w=c;
}
sort(node,node+(m<<));
for(int i=; i<(m<<); ++i){
addEdge(node[i].u,node[i].v,node[i].w);
}
SPFA(n);
cnt=;
memset(vis,,sizeof(vis));
dfs();
NE=;
memset(head,-,sizeof(head));
for(int i=; i<cnt; ++i){
addEdge(node[i].u,node[i].v,node[i].w);
addEdge(node[i].v,node[i].u,node[i].w);
}
memset(vis,,sizeof(vis));
ans_val=; ans_cnt=;
divide();
printf("%d %d\n",ans_val,ans_cnt);
}
return ;
}

HDU4871 Shortest-path tree(最短路径树 + 树的点分治)的更多相关文章

  1. 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)

    [CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...

  2. ZOJ 2760 How Many Shortest Path(最短路径+最大流)

    Description Given a weighted directed graph, we define the shortest path as the path who has the sma ...

  3. Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分

    D. Happy Tree Party     Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...

  4. HDU 4718 The LCIS on the Tree (动态树LCT)

    The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

  5. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  6. 程序员的算法课(19)-常用的图算法:最短路径(Shortest Path)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  7. LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

    P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...

  8. paip.tree 生成目录树到txt后的折叠查看

    paip.tree 生成目录树到txt后的折叠查看 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn.ne ...

  9. 【BZOJ2588】Count On a Tree(主席树)

    [BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...

  10. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

随机推荐

  1. FILE文件操作

    http://www.jb51.net/article/37688.htm fopen(打开文件)相关函数 open,fclose表头文件 #include<stdio.h>定义函数 FI ...

  2. 造成ORA-12560: TNS: 协议适配器错误的问题的原因有三个:

    1.监听服务没有启动 windows平台个一如下操作:开始---程序---管理工具---服务,打开服务面板,启动oraclehome92TNSlistener服务. 2.数据库实例没有启动 windo ...

  3. php提示 Notice: Use of undefined constant name - assumed

    我们知道php在数组中写变量有二几种方法,我们出现这种提示就是你写成了[name]这种所以会有Notice: Use of undefined constant name - assumed name ...

  4. 理解理解python中的'*','*args','**','**kwargs'

    http://blog.csdn.net/callinglove/article/details/45483097 讲了一大堆, 我也是用来理解类继承当中的参数行为的. =============== ...

  5. poj 3321:Apple Tree(树状数组,提高题)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Descr ...

  6. ArcGIS ElementLayer上放置Windows控件

    ElementLayer是ArcGIS API for Silverlight/WPF中的一种图层类型,主要用来承载Silverlight/WPF中的UIElement对象(UIElement),使用 ...

  7. <转>SQL语句执行顺序说明

    原文地址:http://www.cnblogs.com/summer_adai/archive/2011/10/28/2227605.html SQL 不同于与其他编程语言的最明显特征是处理代码的顺序 ...

  8. PHP不同域名cookie共享(单点登录实现原理)

    PHP使用P3P完成COOKIE跨域操作实际实用中,类似的需求有,比如说我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是单点登录(SSO)功能.为了测试的方便,先编辑ho ...

  9. IBM Rational AppScan 无法记录登录序列 分类: 数据安全 2015-03-18 16:46 158人阅读 评论(0) 收藏

    为了测试漏洞,我在本地部署了一个站点,为http://localhost/app,并且有登录页面. 但是尝试多次,都无法记录登录页面.此时尝试了在hosts文件中,自定义了一个域名 127.0.0.1 ...

  10. C# IIS应用程序池辅助类 分类: C# Helper 2014-07-19 09:50 249人阅读 评论(0) 收藏

    using System.Collections.Generic; using System.DirectoryServices; using System.Linq; using Microsoft ...