zoukankan      html  css  js  c++  java
  • 【bzoj3124】[Sdoi2013]直径

    1.求树的直径:

       先随便取一个点,一遍dfs找到离它最远的点l1,再以l1为起点做一遍dfs,找到离l1最远的点l2
       那么l1到l2的距离即为直径
       
    2. 求出有多少条边在这棵树的所有直径上:
       两个结论:
       1)这些边一定在同一条直径上
       2)它们一定是连续的 
       因此,只需要处理第一问求出的直径,从l2到l1求出每个点不经过这条直径所能到达的最远距离,若这个距离==它到l1/l2的距离,则这个点到l1/l2所经过的边都不在答案中,答案边的范围被缩小 

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 using namespace std;
      8  
      9 typedef long long LL;
     10  
     11 #define IN inline
     12 #define RG register
     13  
     14 #define N 400010
     15  
     16 struct edge
     17 {
     18     int to,next;
     19     LL w;
     20 }e[N<<1];
     21 int head[N];
     22 int cnt;
     23  
     24 LL d[N],c[N],f[N],no[N];
     25  
     26 int u,v;
     27 LL w;
     28  
     29 int n;
     30  
     31 int ans;
     32  
     33 LL dis;
     34  
     35 bool flag;
     36  
     37 IN int getint()
     38 {
     39     int x=0,f=1;char ch=getchar();
     40     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     41     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     42     return x*f;
     43 }
     44  
     45 IN int getLL()
     46 {
     47     LL x=0,f=1;char ch=getchar();
     48     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     49     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     50     return x*f;
     51 }
     52  
     53 IN void link(int x,int y,LL z)
     54 {
     55     e[++cnt]=(edge){y,head[x],z};
     56     head[x]=cnt;
     57 }
     58  
     59 IN void dfs(int x,int fa,int & b)
     60 {
     61     f[x]=fa;
     62     if (dis<d[x]) 
     63     { 
     64         dis=d[x]; 
     65         b=x; 
     66     } 
     67     for (RG int i=head[x];i;i=e[i].next)
     68     {
     69         int t=e[i].to;
     70         if (t!=fa)
     71         {
     72             d[t]=d[x]+e[i].w;
     73             dfs(t,x,b);
     74         }
     75     }
     76 }
     77  
     78 IN void work(int x,int fa)
     79 {
     80     if (dis<d[x]) 
     81         dis=d[x]; 
     82     for (RG int i=head[x];i;i=e[i].next)
     83     {
     84         int t=e[i].to;
     85         if (t!=fa && !no[t])
     86         {
     87             d[t]=d[x]+e[i].w;
     88             work(t,x);
     89         }
     90     }
     91 }
     92  
     93 int main()
     94 {
     95     int l1,l2;
     96     n=getint();
     97     for (RG int i=1;i<n;i++)
     98     {
     99         u=getint();v=getint();w=getLL();
    100         link(u,v,w);
    101         link(v,u,w);
    102     }
    103     dfs(1,0,l1);
    104     dis=d[l1]=0;
    105     dfs(l1,0,l2);
    106     printf("%lld
    ",dis);
    107     int l=l1,r=l2;
    108     for (RG int i=l2;i!=0;i=f[i])
    109         no[i]=1; 
    110     for (RG int i=f[l2];i!=l1;i=f[i])
    111     {
    112         int r1=d[i],r2=d[l2]-d[i];
    113         dis=d[i]=0;
    114         work(i,0);
    115         if (dis==r1 && !flag)
    116             l=i,flag=true;
    117         if (dis==r2)
    118             r=i;
    119     }
    120     for (RG int i=r;i!=l;i=f[i])
    121         ans++;
    122     printf("%d",ans);
    123     return 0;
    124 }
  • 相关阅读:
    JDBC连接数据库的四种方式:DriverManager,DataSource,DBCP,C3P0
    下面代码打印的结果?
    当一个线程进入一个对象的synchronized方法A之后,其他线程是否可进入此对象的synchronized方法B?
    线程的sleep()方法和yield()方法有什么区别?
    今天,想说一说明星涉毒
    【译文】为什么用户体验文案在产品设计中如此重要?
    【译文】东京的外国工程师
    浅谈K8S cni和网络方案
    网易云易盾发布多国家多语种内容安全服务,助力中国互联网出海
    如何着手商业数据分析?
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5387174.html
Copyright © 2011-2022 走看看