• 洛谷P2971 牛的*Cow Politics


    题目描述

    Farmer John's cows are living on (N (2 leq N leq 200,000))different pastures conveniently numbered (1..N). Exactly (N-1) bidirectional cow paths (of unit length) connect these pastures in various ways, and each pasture is reachable from any other cow pasture by traversing one or more of these paths (thus, the pastures and paths form a graph called a tree).

    The input for a particular set of pastures will specify the parent node (P_i (0 leq P_i leq N)) for each pasture. The root node will specify parent (P_i == 0), which means it has no parent.

    The cows have organized K$ (1 leq K leq N/2)$ different political parties conveniently numbered (1..K). Each cow identifies with a single

    political party; cow i identifies with political party (A_i (1 leq A_i leq K)). Each political party includes at least two cows.

    The political parties are feuding and would like to know how much 'range' each party covers. The range of a party is the largest distance between any two cows within that party (over cow paths).

    For example, suppose political party (1) consists of cows (1, 3), and (6), political party (2) consists of cows (2, 4), and (5), and the pastures are connected as follows (party 1 members are marked as -(n)-):

    (-3- | -1- / | 2 4 5)

    (| -6-) The greatest distance between any two pastures of political party (1) is (3) (between cows (3) and (6)), and the greatest distance for political party 2 is 2 (between cows (2) and (4), between cows (4) and (5), and between cows (5) and (2)).

    Help the cows determine party ranges.

    TIME LIMIT: (2) seconds

    MEMORY LIMIT: (64)MB

    农夫约翰的奶牛住在(N (2 leq N leq 200,000))片不同的草地上,标号为(1)(N)。恰好有(N-1)条单位长度的双向道路,用各种各样的方法连接这些草地。而且从每片草地出发都可以抵达其他所有草地。也就是说,这些草地和道路构成了一种叫做树的图。输入包含一个详细的草地的集合,详细说明了每个草地的父节点(P_i (0 leq P_i leq N))。根节点的(P_i == 0), 表示它没有父节点。因为奶牛建立了(1)(K)一共(K (1 leq K leq N/2))个政党。每只奶牛都要加入某一个政党,其中, 第i只奶牛属于第(A_i (1 leq A_i leq K))个政党。而且每个政党至少有两只奶牛。 这些政党互相吵闹争。每个政党都想知道自己的“范围”有多大。其中,定义一个政党的范围是这个政党离得最远的两只奶牛(沿着双向道路行走)的距离。

    输入输出格式

    输入格式:

    • Line (1): Two space-separated integers: (N) and (K)

    • Lines (2..N+1): Line (i+1) contains two space-separated integers: (A_i) and (P_i)

    输出格式:

    • Lines (1..K): Line i contains a single integer that is the range of party (i).

    输入输出样例

    输入样例#1:

    6 2 
    1 3 
    2 1 
    1 0 
    2 1 
    2 1 
    1 5 
    

    输出样例#1:

    3 
    2
    

    思路:题意是让你求在树上每个政党的两点间的最远距离,我们可以考虑先把每个政党的最大深度的点找出来,然后(O(n))更新每个政党两点间的最大值,这里还是要通过(LCA)求两点间的树上距离。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 200007
    using namespace std;
    int n,k,num,rt,head[maxn],f[maxn][22],d[maxn],dis[maxn>>1],a[maxn],b[maxn],c[maxn];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct Edge {
      int v,nxt;
    }e[maxn<<1];
    inline void ct(int u, int v) {
      e[++num].v=v;
      e[num].nxt=head[u];
      head[u]=num;
    }
    void dfs(int u, int fa) {
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v!=fa) {
          f[v][0]=u;
          d[v]=d[u]+1;
          dfs(v,u);
        }
      }
    }
    inline int lca(int a,int b) {
      if(d[a]>d[b]) swap(a,b);
      for(int i=20;i>=0;--i)
      if(d[a]<=d[b]-(1<<i)) b=f[b][i];
      if(a==b) return a;
      for(int i=20;i>=0;--i)
      if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
      return f[a][0];
    }
    int main() {
      n=qread(),k=qread();
      for(int i=1,u;i<=n;++i) {
        a[i]=qread(),u=qread();
        if(!u) {rt=i;continue;}
        ct(u,i);ct(i,u);
      }
      dfs(rt,0);
      for(int i=1;i<=n;++i) {
        if(d[i]>b[a[i]]) {
          c[a[i]]=i;
          b[a[i]]=d[i];
        }
      }
      for(int j=1;j<=20;++j)
      for(int i=1;i<=n;++i)
      f[i][j]=f[f[i][j-1]][j-1];
      for(int i=1;i<=n;++i) 
      dis[a[i]]=max(b[a[i]]+d[i]-2*d[lca(c[a[i]],i)],dis[a[i]]);
      for(int i=1;i<=k;++i)
      printf("%d
    ",dis[i]);
      return 0;
    }
    
  • 相关阅读:
    JS中字符串的true转化为boolean类型的true
    jquery select change下拉框选项变化判断选中值
    C# 使用 NPOI 库读写 Excel 文件
    通过微信分享链接,后面被加上from=singlemessage&isappinstalled=1导致网页打不开
    C# 中使用 ThoughtWorks.QRCode.dll 生成指定尺寸和边框宽度的二维码
    除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
    SQL查询语句如何能够让指定的记录排在最后
    搞懂 JavaScript 继承原理
    基于Socket通讯(C#)和WebSocket协议(net)编写的两种聊天功能(文末附源码下载地址)
    SqlServer 使用sys.dm_tran_locks处理死锁问题
  • 原文地址:https://www.cnblogs.com/grcyh/p/10150922.html
Copyright © 2020-2023  润新知