• [IOI2013] dreaming 梦想 题解


    由于题目要使最长路径最短,于是很容易想到贪心策略:


    每棵树和其它树连边的点一定是这棵树上能走到的最远距离最短的的点(由于本人语文水平太菜,这句话有点绕 qwq)

    如果我们把上述的最短距离称作半径 $r$,$1,2,3...$ 是树按照 $r$ 排序后的。那么最后链接成的树应该长这样:

    那么最后的答案只有三种情况:

    1、原树的最长直径

    2、$r_1+r_2+l$

    3、$r_2+r_3+l*2$

    求个 $max$ 就好了~~~

    至于树的半径和直径怎么求。注意到树上离某个点最远的点一定是树的直径的某个端点,于是就可以 $O(n)$ dfs求出。

    /*

    注意每次dfs前清空数组不能用memset,不然效率会被卡到 $O(n^2)$

    我就因为这个T了好久,以为是常数问题,于是代码中加了很多无用的卡常操作,导致它跑的特别快。。。

    */

    代码

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define Int register int
      4 #define N 100005
      5 
      6 inline void rd(int &x){
      7     x=0;char c=getchar();
      8     while(c<'0'||c>'9')c=getchar();
      9     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
     10 }
     11 
     12 int n,m,l;
     13 
     14 int hd[N],_hd;
     15 struct edge{
     16     int v,w,nxt;
     17 }e[N<<1];
     18 inline void addedge(int u,int v,int w){
     19     e[++_hd]=(edge){v,w,hd[u]};
     20     hd[u]=_hd;
     21 }
     22 
     23 bool flg;//为了卡常 
     24 int q[N],_q;
     25 
     26 int dis[2][N];
     27 bool vis[N];
     28 inline void dfs(Int u,Int fa,Int opt){
     29     if(!flg)
     30         q[++_q]=u;
     31     vis[u]=1;
     32     for(Int i=hd[u];i;i=e[i].nxt){
     33         Int v=e[i].v,w=e[i].w;
     34         if(v==fa)
     35             continue;
     36         dis[opt][v]=dis[opt][u]+w;
     37         dfs(v,u,opt);
     38     }
     39 }
     40 
     41 inline int fnd(Int u){
     42     for(Int i=1;i<=_q;i++){
     43         Int v=q[i];
     44         dis[0][q[i]]=0;
     45     }//这里千万不能用memset 
     46     dfs(u,0,0);
     47     flg=1;
     48     Int res=u;
     49     for(Int i=1;i<=_q;i++){
     50         Int v=q[i];
     51         if(dis[0][v]>dis[0][res])
     52             res=v;
     53     }
     54     return res;
     55 }
     56 
     57 int r1,r2,r3,ans,cnt;//r1、r2、r3为前三大的半径,ans一开始为最长直径(第一种情况),cnt表示原来有几棵树 
     58 inline void sol(Int u){
     59     cnt++;
     60     flg=_q=0;
     61     dfs(fnd(fnd(u)),0,1);//最里面的fnd返回的是直径的一个端点,第二个fnd更新dis[0],返回另一个端点,dfs更新dis[1] 
     62     Int r=1e9;
     63     for(Int i=1;i<=_q;i++){
     64         Int v=q[i],disv=std::max(dis[0][v],dis[1][v]);
     65         r=std::min(r,disv);//更新当前树的半径 
     66         ans=std::max(ans,disv);//更新最大直径 
     67     }
     68     if(r>r1){
     69         r3=r2;
     70         r2=r1;
     71         r1=r;
     72     }
     73     else if(r>r2){
     74         r3=r2;
     75         r2=r;
     76     }
     77     else if(r>r3)
     78         r3=r;
     79 }
     80 
     81 int main(){
     82     rd(n),rd(m),rd(l);
     83     for(Int i=1;i<=m;i++){
     84         Int u,v,w;
     85         rd(u),rd(v),rd(w);
     86         addedge(++u,++v,w);
     87         addedge(v,u,w);
     88     }
     89     for(Int i=1;i<=n;i++)
     90         if(!vis[i])
     91             sol(i);
     92     if(cnt>1)
     93         ans=std::max(ans,r1+r2+l);//第二种情况 
     94     if(cnt>2)
     95         ans=std::max(ans,r2+r3+(l<<1));//第三种情况 
     96     printf("%d
    ",ans);
     97 
     98     #define w 0
     99     return ~~('0')?(0^w^0):(0*w*0);
    100 } 
  • 相关阅读:
    初识python 2.x与3.x 区别
    装饰器
    函数的进阶
    Spring Boot启动问题:Cannot determine embedded database driver class for database type NONE
    22.Spring Cloud Config安全保护
    23.Spring Cloud Bus 无法更新问题(踩坑) Spring cloud config server Could not fetch remote for master remote
    24.Spring Cloud之Spring Cloud Config及Spring Cloud Bus
    Spring Boot整合Spring Data Elasticsearch 踩坑
    项目中Spring Security 整合Spring Session实现记住我功能
    32.再谈SpringBoot文件上传
  • 原文地址:https://www.cnblogs.com/Y25t/p/12237174.html
Copyright © 2020-2023  润新知