tarjan+缩点+树的直径
题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少。
先tarjan缩点,再在这棵树上求直径。加的边即是连接这条直径的两端。

  1 /*
  2 tarjan+缩点+树的直径
  3 题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少。
  4 先tarjan缩点,再在这棵树上求直径。加的边即是连接这条直径的两端。
  5 */
  6 #pragma comment(linker, "/STACK:1024000000,1024000000")
  7 #include<stdio.h>
  8 #include<string.h>
  9 #include<stdlib.h>
 10 #include<stack>
 11 #include<algorithm>
 12 #include<iostream>
 13 #include<queue>
 14 #include<map>
 15 #include<math.h>
 16 using namespace std;
 17 typedef long long ll;
 18 //typedef __int64 int64;
 19 const int maxn = 300015;
 20 const int maxm = 2000015;
 21 const int inf = 0x7fffffff;
 22 const double pi=acos(-1.0);
 23 const double eps = 1e-8;
 24 struct Edge{
 25     int v,next;
 26 }edge[ maxm<<1 ],edgeTree[ maxm<<1 ];
 27 int cnt,cnt2,head[ maxn ],head2[ maxn ];
 28 int vis[ maxn ];
 29 int dfn[ maxn ];
 30 int low[ maxn ];
 31 int be[ maxn ];//缩点
 32 int sum;//the num of "缩点"
 33 int id;
 34 stack<int>sta;
 35 queue<int>q;
 36 int maxNode,maxs;//这棵树的直径maxs
 37 int dis[ maxn ];
 38 map<int,int>mp;
 39 void init(){
 40     cnt = cnt2 = 0;
 41     id = 0;
 42     sum = 0;
 43     //mp.clear();
 44     memset( head,-1,sizeof( head ) );
 45     memset( head2,-1,sizeof( head2 ) );
 46     memset( dfn,-1,sizeof( dfn ) );
 47     memset( vis,-1,sizeof( vis ) );
 48     memset( low,-1,sizeof( low ) );
 49     while( !sta.empty() )
 50         sta.pop();
 51 }
 52 void addedge( int a,int b ){
 53     edge[ cnt ].v = b;
 54     edge[ cnt ].next = head[ a ];
 55     head[ a ] = cnt++;
 56 }
 57 void addedge2( int a,int b ){
 58     edgeTree[ cnt2 ].v = b;
 59     edgeTree[ cnt2 ].next = head2[ a ];
 60     head2[ a ] = cnt2++;
 61 }
 62
 63 void tarjan( int u,int Link ){
 64     dfn[ u ] = low[ u ] = id++;
 65     vis[ u ] = 1;
 66     sta.push( u );
 67     int cc = 0;
 68     for( int i=head[u];i!=-1;i=edge[i].next ){
 69         int v = edge[ i ].v;
 70         if( dfn[ v ]==-1 ){
 71             tarjan( v,u );
 72             low[ u ] = min( low[ u ],low[ v ] );
 73         }
 74         else if( Link==v ){
 75             if( cc ) low[ u ] = min( low[ u ],dfn[ v ] );
 76             cc++;
 77         }
 78         else if( vis[ v ]==1 ){
 79             low[ u ] = min( low[ u ],dfn[ v ] );
 80         }
 81     }
 82     if( dfn[u]==low[u] ){
 83         sum++;
 84         int tt;
 85         while( 1 ){
 86             tt = sta.top();
 87             sta.pop();
 88             vis[ tt ] = 0;
 89             be[ tt ] = sum;
 90             if( tt==u ) break;
 91         }
 92     }
 93 }
 94 void buildTree( int n ){
 95     for( int i=1;i<=n;i++ ){
 96         for( int j=head[ i ];j!=-1;j=edge[ j ].next ){
 97             if( be[i]!=be[edge[j].v] ){
 98                 addedge2( be[i],be[edge[j].v] );
 99             }
100         }
101     }
102 }
103 void bfs( int s,int n ){
104     memset( vis,0,sizeof( vis ) );
105     vis[ s ] = 1;
106     while( !q.empty() )
107         q.pop();
108     q.push( s );
109     dis[ s ] = 0;
110     maxs = 0;
111     while( !q.empty() ){
112         int cur = q.front();
113         q.pop();
114         if( dis[ cur ]>=maxs ){
115             maxs = dis[ cur ];
116             maxNode = cur;
117         }
118         for( int i=head2[ cur ];i!=-1;i=edgeTree[ i ].next ){
119             int v = edgeTree[ i ].v;
120             if( vis[ v ]==1 ) continue;
121             vis[ v ] = 1;
122             dis[ v ] = dis[ cur ]+1;
123             q.push( v );
124         }
125     }
126     return ;
127 }
128 int dfs(int u,int p)
129 {
130     int max1=0,max2=0;
131     for (int i=head2[u];i!=-1;i=edgeTree[i].next)
132     {
133         int v=edgeTree[i].v;
134         if (v==p) continue;
135         int tmp=dfs(v,u)+1;
136         if (max1<tmp) max2=max1,max1=tmp;
137         else if (max2<tmp) max2=tmp;
138     }
139     maxs=max(maxs,max1+max2);
140     return max1;
141 } //dfs求树的直径 ok
142 int main(){
143     int n,m;
144     while( scanf("%d%d",&n,&m)&&(n+m) ){
145         int a,b;
146         init();
147         while( m-- ){
148             scanf("%d%d",&a,&b);
149             if( a==b ) continue;
150             //if( mp[min(a,b)] == max(a,b) ) continue;
151             //mp[min(a,b)] = max(a,b);
152             //不能这样去重边???
153             addedge( a,b );
154             addedge( b,a );
155         }
156         for( int i=1;i<=n;i++ ){
157             if( dfn[i]==-1 ){
158                 tarjan( i,-1 );
159             }
160         }
161         buildTree( n );
162         bfs( 1,sum );
163         bfs( maxNode,sum );
164         //printf("sum=%d, maxs=%d\n",sum,maxs);
165         //maxs = 0;
166         //dfs( 1,-1 );
167         printf("%d\n",sum-1-maxs);
168     }
169     return 0;
170 }

View Code

转载于:https://www.cnblogs.com/xxx0624/p/3251907.html

HDU4612+Tarjan缩点+BFS求树的直径相关推荐

  1. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  2. hdu 4607 Park Visit 求树的直径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 Claire and her little friend, ykwd, are travelli ...

  3. 树上子链(树形dp求树的直径)

    树上子链 题意: 给定一棵树 T ,树 T 上每个点都有一个权值. 定义一颗树的子链的大小为:这个子链上所有结点的权值和 . 请在树 T 中找出一条最大的子链并输出. 题解: 求树的直径,题目中存在负 ...

  4. Problem K. Road Network - ACPC2015(求树的直径 dp)

    Problem K. Road Network 题目链接 Arab Collegiate Programming Contest 2015 题意: 树形的公路,如果阻塞道路可以断开两个区域彼此的连接, ...

  5. 求树的直径的两种方法

    树的直径 树型dp求树的直径 优缺点: 优点为可以处理边权为负的情况,但不易得到直径的路径(指树的直径经过什么点). 代码模板: #include<bits/stdc++.h> using ...

  6. 《鲁滨逊漂流记》题解(LCA算法求树的直径)

    Description <鲁滨逊漂流记>只讲到了鲁滨逊在岛上建立起一个自给自足的生态环境.而大家不知道的是,在此之后,鲁滨逊因为太无聊,开始探索周边的岛屿,一共 NNN 天.鲁滨逊第 11 ...

  7. F - Warm up - hdu 4612(缩点+求树的直径)

    题意:有一个无向连通图,现在问添加一条边后最少还有几个桥 分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下 *********************** ...

  8. 求树的直径算法以及证明

    以下为两次dfs(bfs)的做法以及正确性证明. 算法步骤 (1)任取树上一点S,以S为源点BFS得S到各个顶点的d值: (2)取d值最大者之一为P,再以P为源点BFS得P到各个顶点的d值: (3)再 ...

  9. 求树的直径(两种方法)

    ① 两次dfs 方法:先从任意一点P出发,找离它最远的点Q,再从点Q出发,找离它最远的点W,W到Q的距离就是是的直径 证明如下: ①若P已经在直径上,根据树的直径的定义可知Q也在直径上且为直径的一个端 ...

最新文章

  1. 仿站小工具8.0_安卓微信8.0版本可以升级了!新增4个实用功能,内附更新方式...
  2. JAVA _构造函数
  3. 72. Leetcode 99. 恢复二叉搜索树 (二叉搜索树-中序遍历类)
  4. Redis对象类型与编码
  5. Vue中组态实现方案-BaseMap的使用
  6. Java网页开发中model实现Serializable接口的原因
  7. 【LeetCode - 122】买卖股票的最佳时机 II(贪心 或 dp)
  8. 图形学 射线相交算法_计算机图形学中的阴极射线管(CRT)
  9. 再见 Spring Task,这个定时任务框架真香!
  10. Inter Thread Latency
  11. android 初始化类,Android 常用编程技巧/Java类的初始化顺序 (静态变量、静态初始化块、变量、初始化块、构造器)...
  12. java 事件监听应用_Spring Boot应用事件监听示例详解
  13. excel导出_学习笔记—— 前端导出excel
  14. winform窗体——布局方式
  15. 使用Notepad++编辑器查看二进制bin文件
  16. Mac本换ssd注意事项
  17. 眼睛又干又痒,到底是干眼症还是结膜炎?
  18. POJ - Nice Milk(半平面交)
  19. 一篇文章全面了解光纤到户FTTH,光分路器
  20. Kafka 发送消息 Idempotent

热门文章

  1. 用JAVA使用mysql命令操作导入SQL脚本
  2. RabbitMQ生产者和消费者Java实现
  3. Eclipse离线安装Emmet插件----web开发者绝对熟悉的插件之一
  4. java学习日记(1-7)
  5. Node.js使用supervisor遭遇‘supervisor’不是内部或外部命令,如果解决?
  6. 五大最主流浏览器综合性能测试
  7. ASP与ActiveX控件交互实战(一)
  8. java窗体加入声音_我用JAVA写好了一个窗体游戏,怎么加背景音乐?
  9. asa清空配置_Cisco ASA 管理配置文件
  10. Spring-core-SpringFactoriesLoader类