• 牛客小白月赛22


    链接:https://ac.nowcoder.com/acm/contest/4462/B
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 524288K,其他语言1048576K
    64bit IO Format: %lld 

    题目描述

    给定一棵树 T ,树 T 上每个点都有一个权值。
    定义一颗树的子链的大小为:这个子链上所有结点的权值和 。
    请在树 T 中找出一条最大的子链并输出。

    输入描述:

    第一行输入一个 n,1≤n≤105
    接下来一行包含n个数,对于每个数 ai,−105≤ai≤105,表示 i 结点的权值。
    接下来有n-1行,每一行包含两个数u,v( 1≤u,v≤n , u != v),表示u与v之间有一条边。

    输出描述:

    仅包含一个数,表示我们所需要的答案。

    输入

    5
    2 -1 -1 -2 3
    1 2
    2 3
    2 4
    2 5

    输出

    4

    说明

    样例中最大子链为1 -> 2 -> 5

    备注:

    一个结点,也可以称作一条链

    最开始写的有点麻烦(可忽略):

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <string>
      5 #include <math.h>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <stack>
      9 #include <queue>
     10 #include <set>
     11 #include <map>
     12 #include <sstream>
     13 const int INF=0x3f3f3f3f;
     14 typedef long long LL;
     15 const double eps =1e-8;
     16 const int mod=1e9+7;
     17 const int maxn=1e5+10;
     18 using namespace std;
     19 
     20 struct edge
     21 {
     22     int to;
     23     int next;
     24 }E[2*maxn];//注意边的条数 
     25 int head[maxn];
     26 int tot;
     27 void add(int u,int v)
     28 {
     29     E[tot].to=v;
     30     E[tot].next=head[u];
     31     head[u]=tot++;
     32 }
     33 
     34 LL val[maxn];
     35 int in[maxn];
     36 int out[maxn];
     37 LL ans;
     38 
     39 LL DFS(int u,int fa)
     40 {
     41     if(out[u]==1&&fa!=-1)
     42         return val[u]<0? 0:val[u];
     43     priority_queue<LL,vector<LL>,greater<LL> > qe;//维护子链返回的两个最大值 
     44     for(int i=head[u];i!=-1;i=E[i].next)
     45     {
     46         int v=E[i].to;
     47         if(v==fa) continue;
     48         LL t=DFS(v,u);
     49         if(t>0)
     50         {
     51             if(qe.size()<2) qe.push(t);
     52             else
     53             {
     54                 LL p=qe.top();
     55                 if(t>p)
     56                 {
     57                     qe.pop(); qe.push(t);
     58                 }
     59             }
     60         }
     61     }
     62     LL res=val[u];
     63     if(qe.size()==1)
     64     {
     65         LL t1=qe.top(); qe.pop();
     66         ans=max(ans,t1);
     67         res+=t1;
     68     }
     69     else if(qe.size()==2)
     70     {
     71         LL t1=qe.top(); qe.pop();
     72         LL t2=qe.top(); qe.pop();
     73         ans=max(ans,t1+t2+val[u]);
     74         res+=t2;
     75     }
     76     return res<0? 0:res;
     77 }
     78 
     79 
     80 int main()
     81 {
     82     #ifdef DEBUG
     83     freopen("sample.txt","r",stdin);
     84     #endif
     85     
     86     int n;
     87     scanf("%d",&n);
     88     ans=-INF;
     89     memset(head,-1,sizeof(head));
     90     for(int i=1;i<=n;i++)
     91     {
     92         scanf("%lld",&val[i]);
     93         ans=max(ans,val[i]);
     94     }
     95     if(ans<=0)
     96     {
     97         printf("%lld
    ",ans);
     98         return 0;
     99     }
    100             
    101     for(int i=1;i<=n-1;i++)
    102     {
    103         int u,v;
    104         scanf("%d %d",&u,&v);
    105         add(u,v); add(v,u);
    106         in[v]++; in[u]++; out[u]++; out[v]++;
    107     }
    108     for(int i=1;i<=n;i++)
    109     {
    110         if(in[i]==1)
    111         {
    112             ans=max(ans,DFS(i,-1));
    113             break;
    114         }
    115     }
    116     printf("%lld
    ",ans);
    117     
    118     return 0;
    119 }
    View Code

    重新写了一遍:

     1 #include <bits/stdc++.h>
     2 typedef long long LL;
     3 const int INF=0x3f3f3f3f; const LL INFF=0x3f3f3f3f3f3f3f3f;
     4 const double eps =1e-8;
     5 const int mod=1e9+7;
     6 const int maxn=1e5+10;
     7 using namespace std;
     8 
     9 LL val[maxn];
    10 vector<int> vt[maxn];
    11 LL ans;
    12 
    13 LL DFS(int u,int fa)
    14 {
    15     LL res=val[u];
    16     LL max1=-INFF,max2=-INFF; 
    17     for(int i=0;i<vt[u].size();i++)
    18     {
    19         int v=vt[u][i];
    20         if(v==fa) continue;
    21         LL t=DFS(v,u);
    22         if(t>0)
    23         {
    24             if(t>=max1) max2=max1, max1=t;
    25             else if(t>max2) max2=t;
    26         }
    27     }
    28     ans=max(ans, val[u]+max(0LL,max1)+max(0LL,max2));
    29     res+=max(0LL,max1);
    30     return res<=0? 0:res;
    31 }
    32 
    33 
    34 int main()
    35 {
    36     #ifdef DEBUG
    37     freopen("sample.txt","r",stdin);
    38     #endif
    39     
    40     int n;
    41     scanf("%d",&n);
    42     ans=-INFF;
    43     for(int i=1;i<=n;i++)
    44     {
    45         scanf("%lld",&val[i]);
    46         ans=max(ans,val[i]);
    47     }
    48     if(ans<=0)
    49     {
    50         printf("%lld
    ",ans);
    51         return 0;
    52     }
    53            
    54     for(int i=1;i<=n-1;i++)
    55     {
    56         int u,v;
    57         scanf("%d %d",&u,&v);
    58         vt[u].push_back(v);
    59         vt[v].push_back(u);
    60     }
    61     ans=max(ans,DFS(1,-1));
    62     printf("%lld
    ",ans);
    63     
    64     return 0;
    65 }

    另一种写法是直接跑两遍DFS就行(类似求树的直径):

     1 #include <bits/stdc++.h>
     2 typedef long long LL;
     3 const int INF=0x3f3f3f3f; const LL INFF=0x3f3f3f3f3f3f3f3f;
     4 const double eps =1e-8;
     5 const int mod=1e9+7;
     6 const int maxn=1e5+10;
     7 using namespace std;
     8 
     9 LL val[maxn];
    10 vector<int> vt[maxn];
    11 LL ans;
    12 int st;
    13 
    14 void DFS(int u,int fa,LL now)
    15 {
    16     now+=val[u];
    17     if(ans<now)
    18     {
    19         ans=now;
    20         st=u;
    21     }
    22     if(now<0) now=0;
    23     for(int i=0;i<vt[u].size();i++)
    24     {
    25         int v=vt[u][i];
    26         if(v==fa) continue;
    27         DFS(v,u,now);
    28     }
    29 }
    30 
    31 int main()
    32 {
    33     #ifdef DEBUG
    34     freopen("sample.txt","r",stdin);
    35     #endif
    36     
    37     int n;
    38     scanf("%d",&n);
    39     ans=-INFF;
    40     for(int i=1;i<=n;i++)
    41         scanf("%lld",&val[i]);  
    42     for(int i=1;i<=n-1;i++)
    43     {
    44         int u,v;
    45         scanf("%d %d",&u,&v);
    46         vt[u].push_back(v);
    47         vt[v].push_back(u);
    48     }
    49     DFS(1,-1,0);
    50     DFS(st,-1,0);
    51     printf("%lld
    ",ans);
    52     
    53     return 0;
    54 }

    -

  • 相关阅读:
    windows server 2008 远程桌面(授权、普通用户登录)~ .
    UNdelete
    获取当某个表所有索引使用情况
    独特的deadlock(仅update语句也能造成死锁)
    C#全屏截图
    Android OpenGL ES 开发(九): OpenGL ES 纹理贴图
    Android 视频展示控件之 SurfaceView、GLSurfaceView、SurfaceTexture、TextureView 对比总结
    Android 开发使用第三方库出现Crash时处理方案汇总
    Android TV 电视调试和遥控器事件监听
    Android KeyCode 列表
  • 原文地址:https://www.cnblogs.com/jiamian/p/12536268.html
Copyright © 2020-2023  润新知