代码源 #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