zoukankan      html  css  js  c++  java
  • 洛谷 P4408 [NOI2003] 逃学的小孩 题解

    Analysis

    题意虽然说先去谁家再去谁家,但是我们不需要管这个,因为AA、BB、CC三个点我们可以任意互相交换它们所代表的对象,所以题目要求的就是在一棵树上找到3个点AA、BB、CC令AB+BCAB+BC最大,同时要满足AC>ABAC>AB。

    由于这是一棵树,它满足非常可爱的性质,就是如果找一个点出去两条路径使它们的合最大,那么一条是直径时一定会存在一种最大的方案。

    所以我们可以使要找的两条路径其中一条是直径(设为ABAB),然后枚举剩下的点,找到一个到达直径端点最长的另一条路径,不过因为题目要满足一个AC>ABAC>AB,所以我们需要在每次枚举的时候(设为CC),选择ACAC和BCBC的较小的一条边作为另一条路径。可以看到,若是ACAC是小于BCBC的,则选择的路径是ACAC,实际走的路线是CACA+ABAB,满足题目要求的CA<CBCA<CB,而若是选择的是BCBC,实际路线是CBCB+BABA,也符合题意要求的CB<CACB<CA。

    至此,就可以写出代码了,跑2遍dfs找出直径,再对直径起点和终点跑出对每个点的路径长度,然后计算答案。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define int long long
      6 #define maxn 200000+10
      7 using namespace std;
      8 inline int read() 
      9 {
     10     int x=0;
     11     bool f=1;
     12     char c=getchar();
     13     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
     14     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
     15     if(f) return x;
     16     return 0-x;
     17 }
     18 inline void write(int x)
     19 {
     20     if(x<0){putchar('-');x=-x;}
     21     if(x>9)write(x/10);
     22     putchar(x%10+'0');
     23 }
     24 int n,m,cnt,com,sta,ed,ans;
     25 int dis1[maxn],dis2[maxn],head[2*maxn];
     26 struct node
     27 {
     28     int to,val,nxt;
     29 }edge[2*maxn];
     30 inline void add(int x,int y,int z)
     31 {
     32     cnt++;
     33     edge[cnt].to=y;
     34     edge[cnt].val=z;
     35     edge[cnt].nxt=head[x];
     36     head[x]=cnt++;
     37 }
     38 inline void dfs1_tree_d(int x,int fa)
     39 {
     40     for(int i=head[x];i;i=edge[i].nxt)
     41     {
     42         int to=edge[i].to;
     43         if(to==fa) continue;
     44         dis1[to]=dis1[x]+edge[i].val;
     45         if(dis1[to]>com) 
     46         {
     47             com=dis1[to];
     48             sta=to;
     49         }
     50         dfs1_tree_d(to,x);
     51     }
     52 }
     53 inline void dfs2_tree_d(int x,int fa)
     54 {
     55     for(int i=head[x];i;i=edge[i].nxt)
     56     {
     57         int to=edge[i].to;
     58         if(to==fa) continue;
     59         dis2[to]=dis2[x]+edge[i].val;
     60         if(dis2[to]>com) 
     61         {
     62             com=dis2[to];
     63             ed=to;
     64         }
     65         dfs2_tree_d(to,x);
     66     }
     67 }
     68 inline void find1_long(int x,int fa)
     69 {
     70     for(int i=head[x];i;i=edge[i].nxt)
     71     {
     72         int to=edge[i].to;
     73         if(to==fa) continue;
     74         dis1[to]=dis1[x]+edge[i].val;
     75         find1_long(to,x);
     76     }
     77 }
     78 inline void find2_long(int x,int fa)
     79 {
     80     for(int i=head[x];i;i=edge[i].nxt)
     81     {
     82         int to=edge[i].to;
     83         if(to==fa) continue;
     84         dis2[to]=dis2[x]+edge[i].val;
     85         find2_long(to,x);
     86     }
     87 }
     88 signed main()
     89 {
     90 //    freopen("truant.in","r",stdin);
     91 //    freopen("truant.out","w",stdout);
     92     n=read();m=read();
     93     for(int i=1;i<=m;i++)
     94     {
     95         int x=read(),y=read(),z=read();
     96         add(x,y,z);
     97         add(y,x,z);
     98     }
     99     com=0;
    100     dfs1_tree_d(1,0);
    101     com=0;
    102     dfs2_tree_d(sta,0);
    103     ans=dis2[ed];
    104     memset(dis1,0,sizeof(dis1));
    105     memset(dis2,0,sizeof(dis2));
    106     find1_long(sta,0);
    107     find2_long(ed,0);
    108     com=0;
    109     for(int i=1;i<=n;i++)
    110     {
    111         int len=min(dis1[i],dis2[i]);
    112         if(len>com) com=len;
    113     }
    114     ans+=com;
    115     write(ans);
    116     return 0;
    117 }

    请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    C#面向对象三大特性:多态
    C#面向对象三大特性:继承
    C#面向对象三大特性:封装
    C# 函数
    SQL常用语句和函数
    NuGet 常用命令
    SQL Server不同服务器不同数据库间的操作
    C# 面试编程算法题
    C# 冒泡排序
    域名和URL各部分组成
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11628164.html
Copyright © 2011-2022 走看看