当前位置:   article > 正文

Educational Codeforces Round 46 (Rated for Div. 2) E.We Need More Bosses(双连通分量+缩点)_e. we need more bosses 点双联通分量

e. we need more bosses 点双联通分量

题目链接

https://codeforces.com/contest/1000/problem/E

题意

给出一张图,设两点s,t,则可在s,t两点间的必经之边(去掉这条边,s、t不可达)上放置怪物,找到s、t,使得它可放置最多的怪物。输出可放置的最多的怪物。

题解

利用tarjan求出该图的所有边-双连通分量,缩点,形成一棵树,求出树的直径,得到答案。

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int maxn=3e5+10;
  5. void read(int &x){
  6. int f=1;x=0;char s=getchar();
  7. while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
  8. while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
  9. x*=f;
  10. }
  11. struct Edge
  12. {
  13. int no,v,next;
  14. }edges[2*maxn];
  15. int n,m,ebcnum; //节点数目,无向边的数目,边_双连通分量的数目
  16. int e,head[maxn];
  17. int pre[maxn]; //第一次访问的时间戳
  18. int dfs_clock; //时间戳
  19. int isbridge[maxn*2],cl[maxn]; //标记边是否为桥
  20. vector<int> ebc[maxn]; //边_双连通分量
  21. vector<int>mp[maxn];
  22. set<int>ss[maxn];
  23. void addedges(int num,int u,int v) //加边
  24. {
  25. edges[e].no = num;
  26. edges[e].v = v;
  27. edges[e].next = head[u];
  28. head[u] = e++;
  29. edges[e].no = num++;
  30. edges[e].v = u;
  31. edges[e].next = head[v];
  32. head[v] = e++;
  33. }
  34. int dfs_findbridge(int u,int fa) //找出所有的桥
  35. {
  36. int lowu = pre[u] = ++dfs_clock;
  37. for(int i=head[u];i!=-1;i=edges[i].next)
  38. {
  39. int v = edges[i].v;
  40. if(!pre[v])
  41. {
  42. int lowv = dfs_findbridge(v,u);
  43. lowu = min(lowu,lowv);
  44. if(lowv > pre[u])
  45. {
  46. isbridge[edges[i].no] = 1; //桥
  47. }
  48. }
  49. else if(pre[v] < pre[u] && v != fa)
  50. {
  51. lowu = min(lowu,pre[v]);
  52. }
  53. }
  54. return lowu;
  55. }
  56. void dfs_coutbridge(int u,int fa){
  57. ebc[ebcnum].push_back(u);
  58. pre[u] = ++dfs_clock;
  59. for(int i=head[u];i!=-1;i=edges[i].next)
  60. {
  61. int v = edges[i].v;
  62. if(!isbridge[edges[i].no] && !pre[v]) dfs_coutbridge(v,u);
  63. }
  64. }
  65. void init()
  66. {
  67. memset(pre,0,sizeof(pre));
  68. memset(isbridge,0,sizeof(isbridge));
  69. memset(head,-1,sizeof(head));
  70. e = 0; ebcnum = 1;
  71. }
  72. int dep[maxn],vis[maxn],ans=0;
  73. //vector<int>tem;
  74. void dfs(int u){
  75. int i,l1=0,l2=0,f=0;
  76. for(i=0;i<mp[u].size();i++){
  77. int v=mp[u][i];
  78. if(!vis[v]){
  79. f=1;
  80. vis[v]=1;
  81. dfs(v);
  82. if(l1==0){
  83. l1=dep[v]+1;
  84. }
  85. else if(dep[v]+1>l1){
  86. l2=l1;
  87. l1=dep[v]+1;
  88. }
  89. else if(dep[v]+1>l2){
  90. l2=dep[v]+1;
  91. }
  92. }
  93. }
  94. if(!f){
  95. dep[u]=0;return;
  96. }
  97. ans=max(ans,l1+l2);
  98. dep[u]=l1;
  99. }
  100. int ui[maxn],vi[maxn];
  101. int main(){
  102. int i,j;
  103. read(n);read(m);
  104. init();
  105. for(i=0;i<m;i++){
  106. read(ui[i]);read(vi[i]);
  107. addedges(i,ui[i],vi[i]);
  108. }
  109. dfs_findbridge(1,-1);
  110. memset(pre,0,sizeof(pre));
  111. for(i=1;i<=n;i++){
  112. if(!pre[i]){
  113. ebc[ebcnum].clear();
  114. dfs_coutbridge(i,-1);
  115. ebcnum++;
  116. }
  117. }
  118. ebcnum--;
  119. for(i=1;i<=ebcnum;i++){
  120. for(j=0;j<ebc[i].size();j++){
  121. int u=ebc[i][j];
  122. cl[u]=i;
  123. }
  124. }
  125. for(i=0;i<m;i++){
  126. int x=cl[ui[i]],y=cl[vi[i]];
  127. if(!ss[x].count(y)){
  128. ss[x].insert(y);
  129. mp[x].push_back(y);
  130. }
  131. if(!ss[y].count(x)){
  132. ss[y].insert(x);
  133. mp[y].push_back(x);
  134. }
  135. }
  136. memset(vis,0,sizeof(vis));
  137. memset(dep,0,sizeof(dep));
  138. vis[1]=1;
  139. dfs(1);
  140. cout<<ans;
  141. return 0;
  142. }

 

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

闽ICP备14008679号