小P的Civilization V

题目内容

 

小P最近在玩Civilization V,游戏的地图是一棵树,树的每个节点都可以当作战场,刚开始每个节点的战斗加成为00

现在小P拥有两种人员:

一种是工人,每个工人会有一个起点uu和终点vv,工人可以使u->vu>v路径上每个节点的战斗加成+1+1

一种是骑兵,每个骑兵也有一个起点uu和终点vv,骑兵可以选择u->vu>v路径上任意节点战斗

现有mm个工人和qq个骑兵,问每个骑兵作战最多可以拥有多少战斗加成

输入格式

 

第一行三个整数n,m,qn,m,q

接下来一行n-1n1个数,第ii个数f_ifi表示第i+1i+1个节点的父亲

接下来mm行,每行两个整数u,vu,v,表示一个工人

接下来qq行,每行两个整数u,vu,v,表示一个骑兵

输出格式

 

qq行,对于每个骑兵,输出他作战最多可以拥有多少战斗加成

样例 1 输入

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

样例 1 输出

 
3
5
3
5
5

样例 2 输入

 
9 5 5
1 2 2 4 5 3 4 6 
4 9
4 7
1 7
1 2
2 1
9 9
9 9
3 3
7 7
2 2

样例 2 输出

 
1
1
2
2
4

子任务

子任务名评分方式时间限制内存限制说明分数
Subtask 求和 2000 ms 512 MB   100

提示

 

Hint

对于15\%15%的数据,保证n,m,q\le 1000n,m,q1000

对于另外15\%15%的数据,保证f_i=ifi=i

对于另外10\%10%的数据,保证所有u=vu=v

对于另外10\%10%的数据,保证工人的u=vu=v

对于另外10\%10%的数据,保证骑兵的u=vu=v

对于100\%100%的数据,保证n,m,q\le 500,000n,m,q500,000且f_i\le ifii

_________________

没啥难的,树上搜索大集合!

可能是代码能力差,我怎么写这么多搜索!

_________________

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=5e5+10;
  4 struct edge
  5 {
  6     int u,v,nxt;
  7 }e[maxn<<1];
  8 int head[maxn],js;
  9 void addage(int u,int v)
 10 {
 11     e[++js].u=u;e[js].v=v;
 12     e[js].nxt=head[u];head[u]=js;
 13 }
 14 int n,m,q;
 15 int w[maxn],f[maxn][20],dep[maxn];
 16 void dfs(int u,int fa)
 17 {
 18     f[u][0]=fa;dep[u]=dep[fa]+1;
 19     for(int i=1;f[u][i-1];++i)f[u][i]=f[f[u][i-1]][i-1];
 20     for(int i=head[u];i;i=e[i].nxt)
 21     {
 22         int v=e[i].v;
 23         if(v==fa)continue;
 24         dfs(v,u);
 25     }
 26 }
 27 int ff[maxn][20];
 28 void dfs2(int u,int fa)
 29 {
 30     for(int i=head[u];i;i=e[i].nxt)
 31     {
 32         int v=e[i].v;
 33         if(v==fa)continue;
 34         dfs2(v,u);
 35         w[u]+=w[v];
 36     }
 37 }
 38 void dfs3(int u,int fa)
 39 {
 40     ff[u][0]=w[u];
 41     for(int i=1;f[u][i-1];++i)ff[u][i]=max(ff[u][i-1],ff[f[u][i-1]][i-1]);
 42     for(int i=head[u];i;i=e[i].nxt)
 43     {
 44         int v=e[i].v;
 45         if(v==fa)continue;
 46         dfs3(v,u);
 47     }
 48 }
 49 int lca(int u,int v)
 50 {
 51     if(dep[u]<dep[v])swap(u,v);
 52     for(int i=19;i>=0;--i)if(dep[f[u][i]]>=dep[v])u=f[u][i];
 53     if(u==v)return u;
 54     for(int i=19;i>=0;--i)
 55         if(f[u][i]!=f[v][i])
 56         {
 57             u=f[u][i];v=f[v][i];
 58         }
 59     return f[u][0];
 60 }
 61 int lca_(int u,int v)
 62 {
 63     int ans=0;
 64     if(dep[u]<dep[v])swap(u,v);
 65     for(int i=19;i>=0;--i)if(dep[f[u][i]]>=dep[v])ans=max(ans,ff[u][i]),u=f[u][i];
 66     if(u==v)return max(ans,w[u]);
 67     for(int i=19;i>=0;--i)
 68         if(f[u][i]!=f[v][i])
 69         {
 70             ans=max(ans,max(ff[u][i],ff[v][i]));
 71             u=f[u][i];v=f[v][i];
 72         }
 73     ans=max(max(ans,max(w[u],w[v])),w[f[u][0]]);
 74     return ans;
 75 }
 76 int main()
 77 {
 78     scanf("%d%d%d",&n,&m,&q);
 79     for(int v,i=2;i<=n;++i)
 80     {
 81         scanf("%d",&v);
 82         addage(i,v);addage(v,i);
 83     }
 84     dfs(1,0);
 85     for(int u,v,i=1;i<=m;++i)
 86     {
 87         scanf("%d%d",&u,&v);
 88         w[u]++;w[v]++;
 89         int l=lca(u,v);
 90         w[l]--;w[f[l][0]]--;
 91     }
 92     dfs2(1,0);
 93     dfs3(1,0);
 94     for(int u,v,i=1;i<=q;++i)
 95     {
 96         scanf("%d%d",&u,&v);
 97         printf("%d\n",lca_(u,v));
 98     }
 99     return 0;
100 }
View Code

 

posted on 2021-03-31 14:55  gryzy  阅读(82)  评论(0编辑  收藏  举报

导航