其他分享
首页 > 其他分享> > 代码源 #869. Collision

代码源 #869. Collision

作者:互联网

题目描述

siyisss 的王国是由 n 个村镇和 n−1 条双向道路构成的,村镇从 1 到 n 依次编号,每条双向道路连接两个不同的村镇,使得从任意一个村镇出发都可以到达任意一个村镇。接下来请你回答 q 个问题,每次给出两个整数 c, d,表示现在分别有一个人在村镇 c,一个人在村镇 d,现在在 c 的人要用最短的时间到达村镇d,在村镇 d 的人要以最短的时间到达村镇 c,假设两人同时出发,两人的速度也是一样的,每条双向道路的长度也是一样的,请问两人相遇的时候是在某一个村镇,还是在某条双向道路上?

输入描述

第一行输入两个整数 n, q 代表村镇的数量和询问的数量

接下来 n−1 行,每行两个整数用来描述一条双向道路

最后 q,每行两个整数代表 c, d

输出描述

对于每个询问,如果他们在某个村镇相遇,请示出Town,否则输出Road

样例输入1

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

样例输出1

Town
Town

样例输入2

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

样例输处2

Town
Road
Town
Town
Town
Town
Road
Road
Road

数据范围

2≤n≤100000

1≤q≤100000

对于每一个询问 1≤ci<di≤n

 

题目大意:
给一个图,每次询问两个点,求两个点中间是点还是路。

思路:

首先对于两个点,他们之间的距离是奇数的话,他们中间就是道路,他们距离是偶数的话,他们中间就是点。那么问题就转化成了,每次询问两个点,求他们之间的距离是奇数还是偶数。对于每次询问,如果我们都遍历树来求距离的话,肯定是会超时的,所以我们要先预处理一下这棵树。我们可以把1号节点当成根节点,用bfs每次拓展出它的子节点,然后我们给1号节点设定一个值为1,根节点的值为父节点的值+1,如图所示:

 

 可以发现,如果两个节点奇偶性相同,那么这两个节点之间的距离为偶数,反之为奇数,所以在每次询问时判断两节点值的奇偶性即可求解出答案。

 

AC代码(带注释):

 1 #include<algorithm>
 2 #include<iomanip> 
 3 #include<stdio.h>
 4 #include<cstdio>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<cstring>
 8 #include<stack>
 9 #include<queue>
10 #include<string.h>
11 #include<set>
12 #include<map>
13 
14 using namespace std;
15 #define endl '\n'
16 #define ull unsigned long long
17 #define ll long long
18 #define ld long double
19 #define PII pair<int,int>
20 const int N = 1e6 + 7;
21 const int mod = 1e9+7;
22 
23 // 对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点
24 int h[N], e[N], ne[N], idx, a[N];
25 
26 // 添加一条边a->b
27 void add(int a, int b)
28 {
29     e[idx] = b, ne[idx] = h[a], h[a] = idx++;
30 }
31 
32 void bfs()
33 {
34     queue<int> q;
35     a[1] = 1; // 设置根节点距离为1
36     q.push(1);
37 
38     while (q.size())
39     {
40         int t = q.front();
41         q.pop();
42 
43         for (int i = h[t]; i != -1; i = ne[i])
44         {
45             int j = e[i];
46             if (!a[j])//如果没有遍历到
47             {
48                 a[j] = a[t]+1; // 子节点距离为父节点+1
49                 q.push(j);
50             }
51         }
52     }
53 }
54 
55 int main()
56 {
57     //要是超时可能就是没加上这句话
58     ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
59     //初始化
60     idx = 0;
61     memset(h, -1, sizeof h);
62     int n, q;
63     cin >> n >> q;
64     for (int i = 1; i < n; i++)
65     {
66         int x, y;
67         cin >> x >> y;
68         add(x, y); add(y, x);//双向连通
69     }
70     bfs();
71     while (q--)
72     {
73         int x, y;
74         cin >> x >> y;
75         int i = a[x] % 2; int j = a[y] % 2;
76         //如果奇偶性相同,则两点距离为偶数,否则为奇数
77         if (i == j)
78         {
79             //偶数距离会在村庄相遇
80             cout << "Town" << endl;
81         }
82         else
83         {
84             //奇数距离会在道路相遇
85             cout << "Road" << endl;
86         }
87     }
88 
89     return 0;
90 }

 

标签:869,Town,idx,int,代码,Collision,村镇,include,节点
来源: https://www.cnblogs.com/hegege666/p/16304027.html