There are some locations in a park, and some of them are connected by roads. The park manger needs to build some railways along the roads, and he would like to arrange tourist routes to each circuit. If a railway belongs to more than one tourist routes, there might be clash on it, and if a railway belongs to none tourist route, it doesn’t need to build. 
Now we know the plan, and can you tell us how many railways are no need to build and how many railways where clash might happen.

InputThe Input consists of multiple test cases. The first line of each test case contains two integers, n (0 < n <= 10000), m (0 <= m <= 100000), which are the number of locations and the number of the railways. The next m lines, each line contains two integers, u, v (0 <= u, v < n), which means the manger plans to build a railway on the road between u and v. 
You can assume that there is no loop and no multiple edges. 
The last test case is followed by two zeros on a single line, which means the end of the input.OutputOutput the number of railways that are no need to build, and the number of railways where clash might happen. Please follow the format as the sample.Sample Input

8 10
0 1
1 2
2 3
3 0
3 4
4 5
5 6
6 7
7 4
5 7
0 0

Sample Output

1 5

过了一周再来总结这几道题,为什么这道题是每条边访问后就退栈stk[top--],而“warm up”是访问完所以边再退栈。是因为此题不缩点,只是取值,所以不必等访问完所有边再退栈。相反,1-2-4组成一个环,1-3-5组成一个环,点相联通的情况下1-2-4-3-5都应该再这个缩点里,访问完一条边就退栈会导致1-2-4和3-5不在一个缩点里。

比如HDU2242不需要缩点,可以遇到一割边就处理。而HDU4612就必须访问完相连的割边再缩点。

又过了一周,再总结:

   点的双连通存桥(边),每访问一条边操作一次。 

            边的双连通存割点(点),访问完所有边后操作。

尚有疑惑

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
const int maxm=;
int Laxt[maxn],Next[maxm],To[maxm],cnt,vis[maxn];
int dfn[maxn],low[maxn];
int times,ans,cute_cnt,n,m;
int q[maxn],q_cnt,scc[maxn],scc_cnt;
int stk[maxn],top;
void _init()
{
memset(Laxt,,sizeof(Laxt));
memset(dfn,,sizeof(dfn));
memset(scc,,sizeof(scc));
memset(vis,,sizeof(vis));
ans=cute_cnt=top=scc_cnt=cnt=times=;
}
void _add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
}
void _count()//找环
{
int e=;
for(int i=;i<=q_cnt;i++)
for(int j=Laxt[q[i]];j;j=Next[j])
if(scc[To[j]]==scc[q[i]]) e++;
e/=;
if(e>q_cnt) ans+=e;
}
void _tarjan(int u,int v){
dfn[u]=low[u]=++times;
int num_v=;
stk[++top]=u;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]==v) continue;//此题无重边
if(!dfn[To[i]]){
_tarjan(To[i],u);
if(low[u]>low[To[i]]) low[u]=low[To[i]];
if(low[To[i]]>dfn[u]) cute_cnt++;//割边
if(dfn[u]<=low[To[i]]){//小于是个环,等于是个点,都要处理
q_cnt=;//环内的点
scc_cnt++;
for(;;){
int tmp=stk[top--];
scc[tmp]=scc_cnt;
q[++q_cnt]=tmp;
if(tmp==To[i]) break;
}
scc[u]=scc_cnt;
q[++q_cnt]=u;
_count();
}
}
else if(dfn[To[i]]<low[u]) low[u]=dfn[To[i]];
}
}
int main()
{
int i,j,k,u,v;
while(~scanf("%d%d",&n,&m)){
if(n==&&m==) return ;
_init();
while(m--){
scanf("%d%d",&u,&v);
u++;v++;
_add(u,v);
_add(v,u);
}
for(i=;i<=n;i++)
if(!dfn[i]) _tarjan(i,-);
printf("%d %d\n",cute_cnt,ans);
}
return ;
}

HDU3394Railway Tarjan连通算法的更多相关文章

  1. HDU-2586-How far away(LCA Tarjan离线算法)

    链接:https://vjudge.net/problem/HDU-2586 题意: 勇气小镇是一个有着n个房屋的小镇,为什么把它叫做勇气小镇呢,这个故事就要从勇气小镇成立的那天说起了,修建小镇的时候 ...

  2. LCA问题的ST,tarjan离线算法解法

    一  ST算法与LCA 介绍 第一次算法笔记这样的东西,以前学算法只是笔上画画写写,理解了下,刷几道题,其实都没深入理解,以后遇到新的算法要把自己的理解想法写下来,方便日后回顾嘛>=< R ...

  3. LCA最近公共祖先(Tarjan离线算法)

    这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...

  4. LCA(最近公共祖先)--tarjan离线算法 hdu 2586

    HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  5. 最近公共祖先LCA Tarjan 离线算法

    [简介] 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问.换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法. [原理] 先来看这样一个性质:当两个节点 ...

  6. tarjan图论算法

    tarjan图论算法 标签: tarjan 图论 模板 洛谷P3387 [模板]缩点 算法:Tarjan有向图强连通分量+缩点+DAGdp 代码: #include <cstdio> #i ...

  7. LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现

    首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...

  8. 半连通分量--Tarjan/Kosaraju算法

    一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...

  9. Tarjan系列算法总结(hdu 1827,4612,4587,4005)

    tarjan一直是我看了头大的问题,省选之前还是得好好系统的学习一下.我按照不同的算法在hdu上选题练习了一下,至少还是有了初步的认识.tarjan嘛,就是维护一个dfsnum[]和一个low[],在 ...

随机推荐

  1. 【网络结构】VGG-Net论文解析

    目录 0. 论文链接 1. 概述 2. 网络结构 2.1 卷积核 2.2 池化核 2.3 全连接层 3. 训练 4. 测试 5. 其他 6.参考链接 @ 0. 论文链接 论文链接 1. 概述   VG ...

  2. Objective C NSString 编码成URL 特殊字符处理

    找了一下网上的教程都是使用类似以下代码,Xcode提示这个CoreFoundation不受ARC管理,所以折中的方式是添加__bridge. NSString *encodedValue = (__b ...

  3. spring boot 之Rabbitmq 基本配置

    /* * Copyright (c) 2017 4PX Information Technology Co.,Ltd. All rights reserved. */package com.fpx.p ...

  4. 自定义ajax

    // 动态添加script获取里面的数据,,可实现跨域,不跨的当然也可以 getFile:function(params){ try{ //创建script标签 var cbName=params.c ...

  5. 构建hadoop集群时遇到的问题

    在构建hadoop集群时,出现过主节点中的namenode或datanode启动不成功的问题.在日志文件中往往会显示namenode和datanode中clusterID不相同的问题,这个问题往往都是 ...

  6. mysql的基本的数据库的查询

    学习一个数据库我们要学习哪些东西: sql数据库的话, curd. 对于查询,要注意表的关联的查询. 索引,触发器,对于控制连接量,脚本, 数据库的可视化工具,权限管理. http://www.360 ...

  7. 河南省多校联盟二-A

    1279: 简单的背包问题 时间限制: 1 秒  内存限制: 32 MB提交: 361  解决: 20 题目描述 相信大家都学过背包问题了吧,那么现在我就考大家一个问题.有n个物品,每个物品有它的重量 ...

  8. 局部标签(gcc对c的扩展)

    每个语句内嵌表达式都是一个可以声明局部跳转标签的域.一个局部标签只是一个标识符:你可以使用通常的goto语句跳到它--但是只能在它所属的域内这么做.一个局部标签的申明如下:__label__ labe ...

  9. 虚拟机中安装windows server 2008方法

    我们简单的介绍一下怎么在虚拟机上安装 windows server  2008系统. 工具/原料 已经安装好的虚拟机. windows server  2008 iso系统镜像 方法/步骤1虚拟机上虚 ...

  10. Python中面向对象的一些关于类变量与实例变量的理解

    1. 要写出有意义的面向对象的代码,最核心的:类.对象.三大特性:继承.封装.多态 类变量与实例变量: class Student(): # 类变量 name = '张' age = 0 def __ ...