当前位置:   article > 正文

C语言-蓝桥杯2023年第十四届省赛真题-砍树_蓝桥杯砍树

蓝桥杯砍树

题目描述

给定一棵由 n 个结点组成的树以及 m 个不重复的无序数对 (a1, b1), (a2, b2),

. . . , (am, bm),其中 ai 互不相同,bi 互不相同,ai ≠ bj(1 ≤ i, j ≤ m)。

小明想知道是否能够选择一条树上的边砍断,使得对于每个 (ai , bi) 满足 ai和 bi 不连通,如果可以则输出应该断掉的边的编号(编号按输入顺序从 1 开始),否则输出 -1.

输入格式

输入共 n + m 行,第一行为两个正整数 n,m。

后面 n − 1 行,每行两个正整数 xi,yi 表示第 i 条边的两个端点。

后面 m 行,每行两个正整数 ai,bi。

输出格式

一行一个整数,表示答案,如有多个答案,输出编号最大的一个。

样例输入

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

样例输出

4

提示

断开第 2 条边后形成两个连通块:{3, 4},{1, 2, 5, 6},满足 3 和 6 不连通,4 和 5 不连通。

断开第 4 条边后形成两个连通块:{1, 2, 3, 4},{5, 6},同样满足 3 和 6 不连通,4 和 5 不连通。

4 编号更大,因此答案为 4。

对于 30% 的数据,保证 1 < n ≤ 1000。

对于 100% 的数据,保证 1 < n ≤ 105,1 ≤ m ≤ 2/n。

解题:

  1. #include <iostream>
  2. #include <queue>
  3. #include <map>
  4. #include <set>
  5. #include <stack>
  6. #include <string>
  7. #include<functional>
  8. #include <math.h>
  9. #include <algorithm>
  10. #include<unordered_map>
  11. #include<ctime>
  12. #include <cstring>
  13. #define lowbit(x) (-x) & x
  14. #define ll long long
  15. const int N = 3e6;
  16. using namespace std;
  17. const int mod = 1e9 + 7;
  18. ll __pow(ll x,ll y){
  19. ll res = 1;
  20. while(y){
  21. if(y&1)res = (res * x);
  22. y>>=1;
  23. x = (x * x);
  24. }
  25. return res;
  26. }
  27. ll cal(ll v1, ll v2){
  28. return v1*__pow(v2,mod-2)%mod;
  29. }
  30. ll C(ll x,ll y){
  31. ll res = 1;
  32. for(int i = 1,j = x + 1; j <= y;j++, i++){
  33. res*=j;
  34. res/=i;
  35. }
  36. return res;
  37. }
  38. ll gcd(ll x, ll y){
  39. if(y == 0)return x;
  40. else return gcd(y, x%y);
  41. }
  42. struct node{
  43. int to,nxt,c = 0,idx;
  44. }e[N];
  45. int cnt = 0;
  46. int head[N];
  47. void add(int u, int v){
  48. e[++cnt].nxt = head[u];
  49. e[cnt].to = v;
  50. head[u] = cnt;
  51. e[cnt].c = 0;
  52. e[cnt].idx = (cnt + 1)/2;
  53. }
  54. void solve(){
  55. int n,m;
  56. cin>>n>>m;
  57. for(int i = 0; i < n - 1; ++i){
  58. int u,v;
  59. cin>>u>>v;
  60. u--,v--;
  61. add(u, v);
  62. add(v, u);
  63. }
  64. map<ll,int>lca;
  65. vector<int>query[n];
  66. for(int i = 0; i < m;++i){
  67. int u, v;
  68. cin>>u>>v;
  69. u--, v--;
  70. query[u].push_back(v);
  71. query[v].push_back(u);
  72. }
  73. int p[n];
  74. int f[n];
  75. vector<int>diff(n, 0);
  76. vector<int>color(n, 0);
  77. for(int i = 0; i < n;++i)f[i] = i;
  78. function<int(int)>find = [&](int x)->int{return (f[x] == x)?x : f[x] = find(f[x]);};
  79. function<void(int,int)>tarjan = [&](int u,int fa){
  80. color[u] = 1;
  81. p[u] = fa;
  82. for(int i = head[u];i ; i = e[i].nxt){
  83. int v = e[i].to;
  84. if(color[v]==0){
  85. tarjan(v, u);
  86. f[v] = u;
  87. }
  88. }
  89. for(int v : query[u]){
  90. if(color[v]==2 || u == v){
  91. int ffa = find(v);
  92. diff[u]++;
  93. diff[v]++;
  94. lca[(ll)u*(1ll<<32) + v] = ffa;
  95. lca[(ll)v*(1ll<<32) + u] = ffa;
  96. diff[ffa]-=2;
  97. }
  98. }
  99. color[u] = 2;
  100. };
  101. tarjan(0, -1);
  102. int maxe = -1;
  103. function<void(int,int)>dfs = [&](int u, int fa){
  104. for(int i = head[u];i; i = e[i].nxt){
  105. int v = e[i].to;
  106. if(v == fa)continue;
  107. dfs(v, u);
  108. int id = e[i].idx;
  109. diff[u] += diff[v];
  110. if(diff[v] == m){
  111. maxe = max(maxe, id);
  112. }
  113. }
  114. };
  115. dfs(0, -1);
  116. cout<<maxe<<endl;
  117. }
  118. int main(){
  119. ios::sync_with_stdio(false);
  120. cout.tie(0);
  121. cin.tie(0);
  122. int t;
  123. t = 1;
  124. while(t--){
  125. solve();
  126. }
  127. return 0 ;
  128. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/424722
推荐阅读
相关标签
  

闽ICP备14008679号