zoukankan      html  css  js  c++  java
  • 【BZOJ 4016】 [FJOI2014]最短路径树问题

    题目链接:

      TP

    题解:

       我就是个智障。明明是道大水题,硬是拖了6h。

      关于这道题我唯一想说的就是,记得更新拆分后的子树大小!!!我就是ZZ恒(QwQ。

    代码:

      

      1 #define Troy 10/26/2017
      2 
      3 #include <bits/stdc++.h>
      4 
      5 using namespace std;
      6 
      7 inline int read(){
      8     int s=0,k=1;char ch=getchar();
      9     while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
     10     while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
     11     return s*k;
     12 }
     13 
     14 const int N=3e5+5;
     15 
     16 int n,m,K;
     17 
     18 struct edges{
     19     int v,w;edges *last;
     20 }edge[N<<1],*head[N];int cnt;
     21 
     22 inline void push(int u,int v,int w){
     23     edge[++cnt]=(edges){v,w,head[u]};head[u]=edge+cnt;
     24 }
     25 
     26 int q[N],dis[N],from[N];
     27 bool vis[N];
     28 
     29 inline void dfs(int x){
     30     vis[x]=true;
     31     vector<int > G; 
     32     for(edges *i=head[x];i;i=i->last)   if(!vis[i->v]&&dis[i->v]==dis[x]+i->w)
     33         G.push_back(i->v);
     34     sort(G.begin(),G.end());
     35     for(int i=0;i<G.size();i++){
     36         if(vis[G[i]])   continue;
     37         dfs(G[i]);
     38         from[G[i]]=x;
     39     }
     40 }
     41 
     42 inline void spfa(){
     43     int l=0,r=1;
     44     q[0]=1;
     45     memset(dis,127,sizeof(dis));
     46     dis[1]=0;
     47     while(l!=r){
     48         int x=q[l++];if(l==N)   l=0;
     49         for(edges *i=head[x];i;i=i->last){
     50             if(dis[x]+i->w<dis[i->v]){
     51                 dis[i->v]=dis[x]+i->w;
     52                 if(!vis[i->v])
     53                     vis[i->v]=true,q[r++]=i->v;
     54                 if(r==N)    r=0;
     55             }
     56         } 
     57         vis[x]=false;
     58     }
     59     dfs(1);
     60 }
     61 
     62 int heavy[N],root,size[N],tot,top,ans=0,sum,T[N],t[N],clocks,cnts[N];
     63 
     64 inline void dfs(int x,int fa){
     65     size[x]=1,heavy[x]=0;
     66     for(edges *i=head[x];i;i=i->last)if(i->v!=fa&&(!vis[i->v])){
     67         dfs(i->v,x);
     68         size[x]+=size[i->v];
     69         heavy[x]=max(heavy[x],size[i->v]);
     70     }
     71     heavy[x]=max(heavy[x],tot-size[x]);
     72     if(heavy[x]<=top)
     73         top=heavy[x],root=x;
     74 }
     75 
     76 struct node{
     77     int v,w;
     78     inline friend bool operator <(node x,node y){
     79         return size[x.v]<size[y.v];
     80     }
     81 }sons[N];
     82 
     83 inline void calc(int x,int fa,int w,int deep){
     84     if(T[K-deep]==clocks){
     85         if(ans<t[K-deep]+w)
     86             ans=t[K-deep]+w,sum=0;
     87         if(ans==t[K-deep]+w)
     88             sum+=cnts[K-deep];
     89     }
     90     if(deep+1<K)
     91         for(edges *i=head[x];i;i=i->last)   if(i->v!=fa&&vis[i->v]==0){
     92             calc(i->v,x,w+i->w,deep+1);
     93         }
     94 }
     95 
     96 inline void update(int x,int fa,int w,int deep){
     97     if(T[deep]==clocks){
     98         if(t[deep]<w)
     99             t[deep]=w,cnts[deep]=0;
    100         if(t[deep]==w)
    101             cnts[deep]++;
    102     }
    103     else    T[deep]=clocks,t[deep]=w,cnts[deep]=1;
    104     if(deep<K)
    105         for(edges *i=head[x];i;i=i->last)   if(i->v!=fa&&vis[i->v]==0){
    106             update(i->v,x,w+i->w,deep+1);
    107         }
    108 }
    109 
    110 inline void solve(int x){
    111     clocks++;
    112     top=0x7fffffff;
    113     dfs(x,x);       
    114     vis[root]=true;
    115     x=root;
    116     int num(0);
    117     T[1]=clocks;
    118     for(edges *i=head[x];i;i=i->last)if(vis[i->v]^1){
    119         sons[++num]=(node){i->v,i->w};
    120     }
    121     sort(sons+1,sons+1+num);
    122     for(int i=1;i<=num;i++){
    123         calc(sons[i].v,x,sons[i].w,1);
    124         if(i<num)
    125             update(sons[i].v,x,sons[i].w,2);
    126     }       
    127 
    128     for(edges *i=head[x];i;i=i->last)    if(vis[i->v]^1)
    129     if(size[i->v]>=K){
    130         tot=size[i->v],solve(i->v);
    131     }
    132 
    133 }
    134 
    135 int main(){
    136     n=read(),m=read(),K=read();
    137     for(int i=1,u,v,w;i<=m;i++){
    138         u=read(),v=read(),w=read();
    139         push(u,v,w);push(v,u,w);
    140     }
    141     spfa();
    142     memset(vis,0,sizeof(vis));
    143     memset(head,0,sizeof(head));
    144     cnt=0;
    145     for(int i=2;i<=n;i++)
    146         push(from[i],i,dis[i]-dis[from[i]]),
    147         push(i,from[i],dis[i]-dis[from[i]]);
    148     tot=n;
    149     cnts[1]=1;
    150     solve(1);        
    151     printf("%d %d
    ",ans,sum);
    152 }
  • 相关阅读:
    对象并不一定都是在堆上分配内存的
    Minor GC、Major GC和Full GC之间的区别
    JAVA内存分配与回收策略
    HotSpot虚拟机对象相关内容
    JAVA运行时数据区域
    Java 的强引用、弱引用、软引用、虚引用
    去哪儿网支付系统架构演进(下篇)
    去哪儿网支付系统架构演进(上)
    心智模式:如何改善我们的心智模式?
    心智模式:心智模式成熟的标志
  • 原文地址:https://www.cnblogs.com/Troywar/p/7747411.html
Copyright © 2011-2022 走看看