zoukankan      html  css  js  c++  java
  • 洛谷 P1099 树网的核(树的直径+贪心)

    题目链接:https://www.luogu.com.cn/problem/P1099

    用两边DFS求出直径,用f记录fa,这样就记录下了直径的路径,将直径上的点vis标记为1。然后枚举左右端点(或者尺取法,但不会)。

    贪心考虑对答案的贡献:

    假设直径的两个端点为a和b,当前左右端点为i,j,

    对答案的贡献只有a,i之间的距离、b,j之间的距离、i,j中每个节点的子树的最远距离。

    那么可以对于直径上的每一个节点做一次关于它的子树(除直径)的DFS,找出子树最远距离,存在dt[]中。注意不要每更换一次左右端点就重新求一遍,因为vis
    会影响(坑)。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 int n,s;
     7 const int N=400;
     8 int tot,ans=0x7f7f7f7f,anss,ansss;
     9 int head[N];
    10 int f[N],maxd,dis[N],diss[N],dt[N];
    11 int p,vis[N];
    12 struct node{
    13     int to,next,w;
    14 }edge[N<<1];
    15 void add(int u,int v,int w){
    16     edge[tot].to=v;
    17     edge[tot].next=head[u];
    18     edge[tot].w=w;
    19     head[u]=tot++;
    20 }
    21 void DFS(int u,int fa){
    22     f[u]=fa;
    23     if(maxd<dis[u]){
    24         maxd=dis[u];
    25         p=u;
    26     }
    27     for(int i=head[u];i!=-1;i=edge[i].next){
    28         int v=edge[i].to;
    29         if(vis[v]||v==fa) continue;
    30         vis[v]=1;
    31         dis[v]=dis[u]+edge[i].w;
    32         DFS(v,u);
    33     }
    34 }
    35 void DFSD(int u){
    36     if(diss[u]>maxd) maxd=diss[u];
    37     for(int i=head[u];i!=-1;i=edge[i].next){
    38         int v=edge[i].to;
    39         if(vis[v]) continue;
    40         vis[v]=1;
    41         diss[v]=diss[u]+edge[i].w;
    42         DFSD(v);
    43     }
    44 }
    45 int main(){
    46     memset(head,-1,sizeof(head));
    47     memset(f,-1,sizeof(f));
    48     scanf("%d%d",&n,&s);
    49     for(int i=1;i<n;i++){
    50         int u,v,w;
    51         scanf("%d%d%d",&u,&v,&w);
    52         add(u,v,w); add(v,u,w); 
    53     }
    54     DFS(1,-1);
    55     memset(dis,0,sizeof(dis));
    56     memset(f,-1,sizeof(f));
    57     memset(vis,0,sizeof(vis));
    58     int a=p;
    59     maxd=0;
    60     DFS(p,-1);
    61     int b=p;
    62     memset(vis,0,sizeof(vis));
    63     for(int i=b;i!=-1;i=f[i]) vis[i]=1;
    64     for(int i=b;i!=-1;i=f[i]){
    65         for(int j=i;j!=-1&&dis[i]-dis[j]<=s;j=f[j]){
    66             anss=max(dis[b]-dis[i],dis[j]);
    67             for(int k=i;k!=f[j];k=f[k]){
    68                 maxd=0;
    69                 if(dt[k]) maxd=dt[k];
    70                 else { DFSD(k); dt[k]=maxd;}
    71                 anss=max(anss,maxd);
    72             }
    73             ans=min(ans,anss);
    74         }
    75     }
    76     printf("%d",ans);
    77     return 0;
    78 }
    AC代码
  • 相关阅读:
    JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
    有空必看
    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换
    FusionCharts JavaScript API Column 3D Chart
    FusionCharts JavaScript API
    FusionCharts JavaScript API
    Extjs 继承Ext.Component自定义组件
    eclipse 彻底修改复制后的项目名称
    spring 转换器和格式化
    Eclipse快速生成一个JavaBean类的方法
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13698081.html
Copyright © 2011-2022 走看看