1776: [Usaco2010 Hol]cowpol 奶牛政坛
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 491 Solved: 240
[Submit][Status][Discuss]
Description
农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N。恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地。而且从每片草地出发都可以抵达其他所有草地。也就是说,这些草地和道路构成了一种叫做树的图。输入包含一个详细的草地的集合,详细说明了每个草地的父节点P_i (0 <= P_i <= N)。根节点的P_i == 0, 表示它没有父节点。因为奶牛建立了1到K一共K (1 <= K <= N/2)个政党。每只奶牛都要加入某一个政党,其中, 第i只奶牛属于第A_i (1 <= A_i <= K)个政党。而且每个政党至少有两只奶牛。 这些政党互相吵闹争。每个政党都想知道自己的“范围”有多大。其中,定义一个政党的范围是这个政党离得最远的两只奶牛(沿着双向道路行走)的距离。 比如说,记为政党1包含奶牛1,3和6,政党2包含奶牛2,4和5。这些草地的连接方式如下图所 示(政党1由-n-表示): 政党1最大的两只奶牛的距离是3(也就是奶牛3和奶牛6的距离)。政党2最大的两只奶牛的距离是2(也就是奶牛2和4,4和5,还有5和2之间的距离)。 帮助奶牛们求出每个政党的范围。
Input
* 第一行: 两个由空格隔开的整数: N 和 K * 第2到第N+1行: 第i+1行包含两个由空格隔开的整数: A_i和P_i
Output
* 第1到第K行: 第i行包含一个单独的整数,表示第i个政党的范围。
Sample Input
6 2
1 3
2 1
1 0
2 1
2 1
1 5
1 3
2 1
1 0
2 1
2 1
1 5
Sample Output
3
2
2
HINT
Source
这个题其实比较简单,然而我还是不会......我菜得抠脚
需要知道这样的一个事情,路径最长的两端点其中必定有一点是该党派中deep[i]最深的那个点,这个应该是显然......
然而我刚看题的时候天真地认为两段点应该是deep[i]最深的两个点......
当然这个题可以用一个n*n的暴力枚举,不过显然是要TLE。
突然觉得vector真是好用,此题中会非常方便地查找一党派中deep[i]最大的那个点
我废话真多,多半是我太渣,唉......
这个题,用手写的read竟然比scanf慢,震惊!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 int n,k,root,ans,mxdeep,mx; 8 int father[200010],group[200010],deep[200010],fa[200010][32]; 9 vector<int>child[200010],party[200010]; 10 void dfs(int u){ 11 fa[u][0]=father[u]; 12 deep[u]=deep[father[u]]+1; 13 for(int i=1;(1<<i)<=n;i++) fa[u][i]=fa[fa[u][i-1]][i-1]; 14 for(int i=0;i<child[u].size();i++) dfs(child[u][i]); 15 } 16 int lca(int u,int v){ 17 if(deep[u]<deep[v]) swap(u,v); 18 int i=0; 19 for(i=0;(1<<i)<=n;i++); 20 i--; 21 for(int j=i;j>=0;j--) 22 if(deep[u]-(1<<j)>=deep[v]) u=fa[u][j]; 23 if(u==v) return u; 24 for(int j=i;j>=0;j--) 25 if(fa[u][j]!=fa[v][j]){ 26 u=fa[u][j]; 27 v=fa[v][j]; 28 } 29 return father[u]; 30 } 31 int main(){ 32 scanf("%d%d",&n,&k); 33 for(int i=1;i<=n;i++){ 34 scanf("%d%d",&group[i],&father[i]); 35 child[father[i]].push_back(i); 36 party[group[i]].push_back(i); 37 if(!father[i]) root=i; 38 } 39 dfs(root); 40 for(int i=1;i<=k;i++){ 41 ans=0; 42 mxdeep=0; 43 mx=0; 44 for(int j=0;j<party[i].size();j++) 45 if(deep[party[i][j]]>mxdeep){ 46 mxdeep=deep[party[i][j]]; 47 mx=party[i][j]; 48 } 49 for(int j=0;j<party[i].size();j++) 50 ans=max(ans,deep[mx]+deep[party[i][j]]-2*deep[lca(mx,party[i][j])]); 51 printf("%d ",ans); 52 } 53 return 0; 54 }