<题目链接>

题目大意:
给定一个$n$个节点$m$条边的无向图,问你对任意两点,最多有多少条特殊边,特殊边指删除这条边后,这两个点不能够到达。

解题分析:

特殊变其实就是指割边,题意就是问你任意两点的路径之间,割边的最大数量。比较裸的题目,由边双连通和树的直径拼凑而成。

用边双连通缩完点之后,树形DP算出最长链即可。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. template<typename T>
  4. inline void read(T&x){
  5. x=;int f=;char ch=getchar();
  6. while(ch<'' ||ch>''){ if(ch=='-')f=-; ch=getchar(); }
  7. while(ch>='' && ch<=''){ x=x*+ch-''; ch=getchar(); }
  8. x*=f;
  9. }
  10. #define pb push_back
  11. #define REP(i,s,t) for(int i=s;i<=t;i++)
  12. #define clr(a,b) memset(a,b,sizeof(a))
  13. const int N = 3e5+;
  14. int n,m,tot,top,bcc;
  15. int head1[N],head2[N],dfn[N],bel[N],cnt1,cnt2;
  16. int low[N],instk[N],stk[N];
  17. vector<int>G[N];
  18. struct Edge{ int from,to,nxt; }e1[N<<],e2[N<<];
  19. int ans;
  20. inline void init(){
  21. REP(i,,n)G[i].clear();
  22. cnt1=cnt2=tot=top=bcc=;
  23. clr(dfn,);clr(bel,);
  24. clr(head1,-);clr(head2,-);
  25. }
  26. inline void add1(int u,int v){
  27. e1[cnt1]=(Edge){u,v,head1[u]};head1[u]=cnt1++;
  28. }
  29. inline void add2(int u,int v){
  30. e2[cnt2]=(Edge){u,v,head2[u]};head2[u]=cnt2++;
  31. }
  32. void Tarjan(int u,int pre){
  33. dfn[u]=low[u]=++tot;
  34. instk[u]=;stk[++top]=u;
  35. bool fp=false;
  36. for(int i=head1[u];~i;i=e1[i].nxt){
  37. int v=e1[i].to;
  38. if(v==pre && !fp){ fp=true;continue; }
  39. if(!dfn[v]){
  40. Tarjan(v,u);
  41. low[u]=min(low[u],low[v]);
  42. }else if(instk[v])low[u]=min(low[u],dfn[v]);
  43. }
  44. if(dfn[u]==low[u]){
  45. ++bcc;
  46. while(true){
  47. int v=stk[top--];
  48. instk[v]=;
  49. bel[v]=bcc;
  50. G[bcc].pb(v);
  51. if(u==v)break;
  52. }
  53. }
  54. }
  55. inline void getMap(){
  56. for(int i=;i<cnt1;i++){ //缩点
  57. int u=e1[i].from,v=e1[i].to;
  58. if(bel[u]!=bel[v])add2(bel[u],bel[v]);
  59. }
  60. }
  61.  
  62. int dp1[N],dp2[N];
  63. //树形DP求树的直径
  64. void dfs(int u,int pre){
  65. for(int i=head2[u];~i;i=e2[i].nxt){
  66. int v=e2[i].to;
  67. if(v==pre)continue;
  68. dfs(v,u);
  69. if(dp1[v]+>dp1[u])dp2[u]=dp1[u],dp1[u]=dp1[v]+;
  70. else if(dp1[v]+>dp2[u])dp2[u]=dp1[v]+;
  71. }
  72. ans=max(ans,dp1[u]+dp2[u]);
  73. }
  74.  
  75. int main(){
  76. init();
  77. read(n);read(m);
  78. REP(i,,m){
  79. int u,v;read(u);read(v);
  80. add1(u,v);add1(v,u);
  81. }
  82. Tarjan(,-);
  83. getMap();
  84. dfs(,-); //进行树形DP求最长链
  85. cout<<ans<<endl;
  86. }

Codeforces 1000E We Need More Bosses (边双连通+最长链)的更多相关文章

  1. CodeForces - 1000E We Need More Bosses

    题面在这里! 依然一眼题,求出割边之后把图缩成一棵树,然后直接求最长链就行了2333 #include<bits/stdc++.h> #define ll long long using ...

  2. E - We Need More Bosses CodeForces - 1000E (tarjan缩点,树的直径)

    E - We Need More Bosses CodeForces - 1000E Your friend is developing a computer game. He has already ...

  3. 边双连通缩点+树dp 2015 ACM Arabella Collegiate Programming Contest的Gym - 100676H

    http://codeforces.com/gym/100676/attachments 题目大意: 有n个城市,有m条路,每条路都有边长,如果某几个城市的路能组成一个环,那么在环中的这些城市就有传送 ...

  4. poj 3694 Network 边双连通+LCA

    题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...

  5. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

  6. HDU 4612 Warm up (边双连通分量+DP最长链)

    [题意]给定一个无向图,问在允许加一条边的情况下,最少的桥的个数 [思路]对图做一遍Tarjan找出桥,把双连通分量缩成一个点,这样原图就成了一棵树,树的每条边都是桥.然后在树中求最长链,这样在两端点 ...

  7. HDU-4612 Warm up 边双连通分量+缩点+最长链

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 简单图论题,先求图的边双连通分量,注意,此题有重边(admin还逗比的说没有重边),在用targ ...

  8. poj1515--Street Directions(边的双连通)

    给一个无向图,要求变成强连通的有向图,需要保留哪些边. 边的双连通,对于桥保留两条边,其他的只保留一条边.求双连通的过程中记录保留边. /******************************* ...

  9. poj3177--Redundant Paths(边的双连通)

    有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路.两条独立的路是指:没有公共边的路,但可以 ...

随机推荐

  1. 认知redis

    一.redis是什么? 1.基于key-value的内存No sql 数据库(非关系型数据库) 2.读写性能非常好 二.redisd的数据类型有哪些?特点分别是什么? 1)string 一个键对一个值 ...

  2. 微信支付MD5签名算法C#版,ASCII码字典序排序0,A,B,a,b

    /// <summary> /// 微信支付MD5签名算法,ASCII码字典序排序0,A,B,a,b /// </summary> /// <param name=&qu ...

  3. js函数总结

    最近要经常写一些Js代码,总看到同事能使用js高级函数写出比较简洁的js代码,挺羡慕的,于是就花了一些专门时间来学习. forEach.map.reduce 我就不喜欢一上来就给出语法来,先来一个例子 ...

  4. lsattr 查看文件扩展属性

    1. 命令功能 lsattr查看 是否有chattr设置的权限. 2. 使用范例 [root@localhost data]# lsattr resolv.conf -----a-------e- r ...

  5. [php代码审计] php://filter

    筛选过滤应用: 1. 字符串过滤器: string.rot13 对字符串执行ROT13转换 string.toupper转换为大写 string.tolower 转换为小写 string.strip_ ...

  6. super语句不必须放在方法第一行。

    class A(object): pass class B(A): def __init__(self): self.__a = "B#a" super(B, self).__in ...

  7. 详解JVM内存模型与JVM参数详细配置

    对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...

  8. 对Promise的研究3

    Promise.race() Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例. const p = Promise.race([p1, p2, p ...

  9. php strpos()函数 语法

    php strpos()函数 语法 作用:寻找字符串中某字符最先出现的位置.大理石平台怎么选择 语法:strpos(string,find,start) 参数: 参数 描述 string     必需 ...

  10. CKEditor粘贴图片上传功能

    很多时候我们用一些管理系统的时候,发布新闻.公告等文字类信息时,希望能很快的将word里面的内容直接粘贴到富文本编辑器里面,然后发布出来.减少排版复杂的工作量. 下面是借用百度doc 来快速实现这个w ...