题目:

  BZOJ4016最短路径树问题

分析:

  大家都说这是一道强行拼出来的题,属于是两种算法的模板题。

  我们用dijkstra算法算出1为源点的最短路数组,然后遍历一下建出最短路树。

  之后就是裸的点分治算法,一个桶,两个变量就解决了这道题。

代码:

 #include<bits/stdc++.h>
#define pi pair<int,int>
#define pq priority_queue
#define mp(a,b) make_pair(a,b)
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std;
const int N=;
vector< pi >g[N];
struct node{int y,z,nxt;}e[N*];
int n,m,k,h[N],c=,dis[N],vis[N],nm[N];
int ans2,md,rt,sm,siz[N],s[N],ans,f[N];
pq< pi,vector< pi >,greater< pi > >q;
void add(int x,int y,int z){
e[++c]=(node){y,z,h[x]};h[x]=c;
e[++c]=(node){x,z,h[y]};h[y]=c;
} void dij(){
ms(vis,);ms(dis,0x3f);
dis[]=;q.push(mp(,));
while(!q.empty()){
int x=q.top().second;q.pop();
if(vis[x]) continue;vis[x]=;
for(int i=;i<g[x].size();i++){
int y=g[x][i].first,
d=g[x][i].second;
if(dis[y]>dis[x]+d) dis[y]=dis[x]+d,
q.push(mp(dis[y],y));
}
} return ;
} void rebuild(int x){
vis[x]=;
for(int i=;i<g[x].size();i++){
int y=g[x][i].first,d=g[x][i].second;
if(vis[y]||dis[x]+d!=dis[y]) continue;
add(x,y,d);rebuild(y);
} return ;
} void getrt(int x,int fa){
siz[x]=;f[x]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]&&y!=fa) getrt(y,x),
siz[x]+=siz[y],f[x]=max(f[x],siz[y]);
f[x]=max(f[x],sm-siz[x]);
if(f[rt]>f[x]) rt=x;return ;
} void dfs(int x,int fa,int nw){
md=max(md,nw);
if(nw==k-){
if(ans==dis[x]) ans2++;
if(dis[x]>ans) ans2=,
ans=dis[x];return ;
} int nans=-;
if(s[k--nw]!=-) nans=dis[x]+s[k--nw];
if(ans==nans) ans2+=nm[k--nw];
if(nans>ans) ans2=nm[k--nw],ans=nans;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]&&y!=fa)
dis[y]=dis[x]+e[i].z,dfs(y,x,nw+);
} void update(int x,int fa,int nw){
if(nw==k-) return ;
if(s[nw]==dis[x]) nm[nw]++;
else s[nw]=max(s[nw],dis[x]),nm[nw]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]&&y!=fa) update(y,x,nw+);
} void solve(int x){
md=;vis[x]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]) dis[y]=e[i].z,
dfs(y,x,),update(y,x,);
for(int i=;i<=md;i++) s[i]=-,nm[i]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]) sm=siz[y],rt=,
getrt(y,x),solve(rt);
} int main(){
f[]=0x3f3f3f3f;scanf("%d%d%d",&n,&m,&k);
for(int i=,x,y,z;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
g[x].push_back(mp(y,z));
g[y].push_back(mp(x,z));
} for(int i=;i<=n;i++)
sort(g[i].begin(),g[i].end());
dij();ms(vis,);rebuild();
sm=n;rt=;ms(vis,);
ms(dis,);ms(s,-);
getrt(,);solve(rt);
printf("%d %d\n",ans,ans2);
return ;
}

最短路树+点分治

最新文章

  1. AngularJS过滤器filter-时间日期格式-渲染日期格式-$filter
  2. jQuery:实现两个&lt;select&gt;控件的互移操作
  3. 【JAVA】Runtime
  4. 01 Hibernate错题分析
  5. MusigCV安装
  6. 怎么保护PDF文档和扫描文件里的机密信息
  7. sqool导出oracle数据
  8. 【英文】Bingo口语笔记(18) - Cover系列
  9. Loadrunner 运行场景时:missing newline in XXX.dat 错误解决
  10. jQuery Validation让验证变得如此容易(二)
  11. 选择LDO的方法(转)
  12. eclipse如何把多个项目用不同的文件夹分隔开
  13. File API简介
  14. Material04 MdListModule模块
  15. 对使用多个swiper下标有时显示不出来的问题
  16. ABP官方文档翻译 10.1 ABP Nuget包
  17. Error[Pe020]: identifier &quot;FILE&quot; is undefined
  18. 第一章:HTML5的基础
  19. 【mybatis源码学习】mybtias扩展点
  20. RNN(Recurrent Neural Networks)公式推导和实现

热门文章

  1. ko.js循环绑定值问题(工作遇见)
  2. Codeforces Round #542(Div. 2) B.Two Cakes
  3. 洛谷P2514||bzoj2426 [HAOI2010]工厂选址
  4. VMware每次联网都需要还原默认设置解决办法
  5. Hive_Hive的管理_web界面方式
  6. 自己开发shell脚本实现一键化安装。
  7. python 多继承(新式类) 二
  8. 牛客网Java刷题知识点之多线程同步的实现方法有哪些
  9. yield和yield from
  10. CF1061B Views Matter