Tree (四校联考T1)

【题目描述】

方方方种下了三棵树,一年后,第一棵树长出了n个节点。

方方方会向你提出m个询问,每个询问给出两个数i,j,你需要回答i号节点和j号节点在树上的距离。

【输入数据】

第一行两个整数n,m。接下来n-1行每行两个整数a,b表示一条边。接下来m行每行两个整数i,j表示询问。

【输出数据】

m行,每行一个整数表示答案。

【样例输入】

3 2

1 2

1 3

3 2

1 1

【样例输出】

2

0

【数据范围】

对于30%的数据,n,m<=1000。

对于100%的数据,n,m<=500000。

题解:啊mdzz写个LCA啊。。。A到B的距离不就是A到根节点,B到根节点的距离之和减去(LCA到根节点的距离的两倍),今天学了个比较有趣的LCA。。QAQ

传教时间到!

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include <iostream>
 4 #include <cmath>
 5 #include <string>
 6 #include <algorithm>
 7 struct node
 8 {
 9     int from,to,next,val;
10 }edge[2*500001];
11 struct node1
12 {
13     int from,to,next,num;
14 }edge1[2*500001];
15 int tol,head[500001],head1[500001],cnt1,father[500001],dis[500001],LCA[500001],n,m;
16 bool visit[500001];
17 void add(int a,int b,int c)
18 {
19     edge[tol].from=a;
20     edge[tol].to=b;
21     edge[tol].next=head[a];
22     edge[tol].val=c;
23     head[a]=tol++;
24 }
25 void add1(int a,int b,int c)
26 {
27     edge1[cnt1].from=a;
28     edge1[cnt1].to=b;
29     edge1[cnt1].next=head1[a];
30     edge1[cnt1].num=c;
31     head1[a]=cnt1++;
32 }
33 int find(int x)
34 {
35     if(x!=father[x])
36         father[x]=find(father[x]);
37     return father[x];
38 }
39 void tarjan(int u)
40 {
41     int j;
42     visit[u]=1;
43     father[u]=u;
44     for(j=head1[u];j!=-1;j=edge1[j].next)
45       {
46           int temp=edge1[j].to;
47         if (visit[temp])
48           LCA[edge1[j].num]=find(temp);
49       }
50     for(j=head[u];j!=-1;j=edge[j].next)
51       {
52           int temp=edge[j].to;
53         if(!visit[edge[j].to])
54           {
55             dis[temp]=dis[u]+edge[j].val;
56             tarjan(temp);
57             father[temp]=u;
58           }
59       }//xjb dfs...
60 }
61 int main()
62 {
63     int i,a,b;
64     freopen("tree.in","r",stdin);
65     freopen("tree.out","w",stdout);
66     scanf("%d%d",&n,&m);
67     tol=0,cnt1=0;
68     memset(head,-1,sizeof(head));
69     memset(visit,0,sizeof(visit));
70     memset(head1,-1,sizeof(head1));
71     for(i=1;i<=n-1;i++)
72       {
73         scanf("%d%d",&a,&b);
74         add(a,b,1);
75         add(b,a,1);
76       }
77     for(i=1;i<=m;i++)
78       {
79         scanf("%d%d",&a,&b);
80         add1(a,b,i);
81         add1(b,a,i);
82       }
83     dis[1]=0;
84     tarjan(1);
85     for(i=0;i<=cnt1-1;i+=2)
86           printf("%d\n",dis[edge1[i].from]+dis[edge1[i].to]-2*dis[LCA[edge1[i].num]]);
87     return 0;
88 }

传教时间到!

啊这个代码比较核心。。↓

 1 int find(int x)
 2 {
 3     if (x!=father[x])
 4       father[x]=find(father[x]);
 5     return x;
 6 void tarjan(int u)
 7 {
 8     visit[u]=1;
 9     father[u]=u;
10     for (i=g2[u];i!=-1;i=e2[i].next)
11       if (visit[e2[i].to])
12         LCA[e2[i].num]=find(e2[i].to);
13     for (i=g[u];i!=-1;i=e[i].next)
14         {
15           if (!visit[e[i].to])
16             {
17                dis[e[i].to]=dis[u]+e[i].w;
18                tarjan(w[i].to);
19                father[e[i].to]=u;
20             }
21         }
22
23 }

QAQ

啊今天只写过了第一题QAQ。。要完啊

时间: 2024-10-07 13:36:36

Tree (四校联考T1)的相关文章

10.29 FJ四校联考

//四校联考Rank 16 感觉很滋磁 (虽然考的时候抱怨厦门一中出的数学题很NOIP///) 圈地 [问题描述] n根长度不一定相同的木棍,至多可以对其中一根切一刀,然后用其中的任意根围一个三角形,求三角形的最大面积.设面积为S,输出16*S^2对998244353取模后的答案.特别地,无解输出-1. 注:退化的三角形(面积为零)不被认为是三角形,答案应该为-1. [输入文件] 输入文件为tri.in. 输入文件第一行包含两个正整数n和998244353. 第二行包含n个正整数,表示每根木棍的

四校联考2017.8.20T1填算式

由于T2和T3都太高深了太巧妙了,于是只会做T1,拿了95分.现提供95分做法与满分做法 数据范围:n≤13,1≤ai≤9,0≤k≤109 大意:给n个数,在其中填+?×,允许多个数合并为一个.求使得最终结果等于k的算式数量.(这不就是我们平常玩的24点的加强版吗?) 95分解法:我们注意到对于第一个数字,其前面的操作只能为加法,对于之后的每一个数字,我们都有四种操作:在前面填加号,减号,乘号:与前面的数字合并.注意到n的值很小,于是考虑深搜.用两个数组分别记这个算式的符号和数字,当深搜到最后的

2017-3-5四校联考

szy学长出的,除了T3外都比较水 360/400. T1.小猪划船 题目大意:六只猪要过河,三只大猪ABC,三只小猪abc,其中ABCa会划船,共一只船,每次可以载2个人,给出四只猪的划船耗时,每次运载花的时间是船上耗时最小的猪的耗时乘上船上猪的个数,小猪与其对应大猪不在一起时不能与其他大猪在一起,求所有猪到对岸的最小耗时. 思路:状态最多2^7(每只猪还有船的位置),随便建图最短路或者直接搜索或者构造都能通过该题.我写的O(2^21). #include<cstdio> #include&

20170814四校联考

啊啊啊啊啊啊NOIAu大神ysy出题虐菜出人命啦!爆tan(pi/4)啦!被害者家属情绪稳定. ysy大佬谁敢D啊,NOIAu1st了,只适合D人了. 还是IOIAu的大佬体谅人,我还那么蒟蒻呢~ 闲话不说,上题目: T1: 宝石(gem) [题目描述]有 n 座城市,编号为 1~n,第 i 座城市里宝石的交易价格为 ai.当你经过第 i 座城市时,你可以以 ai 的价格购买或卖出一个宝石.在任意时刻,你最多只能携带一个宝石.有 m 次操作,操作分为两种:(1) 给定l,r,询问依次经过编号为l

20170820四校联考

来看看IOIAu巨神zzx的名言 不用循环输入就会狗啊哥哥! 上题目: T1: 填算式(expr) [题目描述] 填算式是一种简单的数学游戏,可以形式化描述如下:n 个数字a1; a2; -- ; an 排成一排(1<= ai<=9),相邻两个数字之间有一个空格.你可以在每个空格内填入运算符+- * 之一,也可以不填,要求得到的算式的运算结果等于k.你的任务是计算有多少种不同的正确算式.比如n = 3,3 个数字为2; 2; 2,k = 24时,有两种不同的正确算式:22 + 2 = 24,2

四校联考——20170730模拟赛

今天3题都很丧. 我只会T1,所以我很弱 T1要有桶排序,不然会T,被卡常 做法就是先排序,然后前缀和乱搞 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #pragma o1 using namespace std; inline int read(){ int x=0;char c=getchar();bool t

2016年9月25日四校联考

·前言:啊f**k今天早上体检,但是并不影响做题2333因为题目真的好 NOIP 啊 啊对了附中评测姬好坑啊正解强行T 23333 第一题<萝卜种子> 简要题意:小姑娘看了看狐狸的萝卜田,发现田里最多只能生长7个萝卜(多余的种子不会发芽),且4种萝卜发芽的概率是完全相同的.它们的效果分别是: 普通萝卜:生产2kg兔粮 超能萝卜:生产2kg兔粮,每种植一个其他萝卜额外产生1kg兔粮 固氮萝卜:不能用于生产兔粮,但能使每个普通萝卜和超能萝卜生产的兔粮+1kg 金坷垃萝卜:不能用于生产兔粮,但能使每

2017-2-19四校联考

T1. #include<cstdio> #include<cstring> #define MN 300 int a[MN+5][MN+5],f[2][1<<17]; int main() { freopen("design.in","r",stdin); freopen("design.out","w",stdout); int n,m,p,i,j,k,x,p1,p2; scanf(&q

2017-4-9四校联考

T2结论推得有点问题结果只有30,T3暴力骗了40,170/300 T1.交易 题目大意:一个人从0走到m,走1要1s,路上有n个点xi,每个点必须被经过2次,第二次要在第一次的ts之后经过才算数,求最少时间.(n<=3,000,000,0<xi<m<=10^9) 思路:f[i]表示完成前i个点后到达第i个点的最小时间,每次回头显然必须完成所有之前未完成的点,故有f[i]=min(f[j]+x[i]-x[j]+max(2*(x[i]-x[j+1]),t)),把max分开讨论,当2*