HDU1269 有向图强连通分量
题目大意:问一个有向图是否任意两点在两个方向上互相连通。
有向图强连通分量定义:如果一个图中的任意两点在两个方向上都互相连通,则该图为强连通图。极大强连通图为有向图的强连通分量(注意是极大,不是最大。一个图会有多个强连通分量)。感性理解,强连通图就是多个环,或者一个点连接在一起所产生的图。
如何求?定义节点cur->Low,cur的子搜索树节点a中如果存在边(a,b),使得b->DfsN小于cur->DfsN,则cur->Low=min foreach b{b->DfsN},否则为cur->DfsN。显然,cur->Low所对应的节点位于cur所在极大强连通分量中,且是cur所在环中深度最浅的。
新定义一个栈维护一组节点,其使得处理完栈内节点cur以上的节点后,cur以上节点的Low <= cur->Low(它们位于cur子搜索树中的各个枝杈上(而不仅仅存在于一个枝杈中,这是系统栈所做不到的),不存在满足该条件却不在该栈内的节点),即cur及以上节点在一个强连通分量内。如果cur->Low == cur->DfsN,则cur是其所在强连通分量中深度最浅的,再往栈下面走的节点就不属于这个连通分量了,此时便可以输出连通分量,然后将cur及以上节点全部弹出。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; const int MAX_NODE = 10010, MAX_EDGE = 100010; struct Node;
struct Edge; struct Node
{
int Id, DfsN, Low;
Edge *Head;
}_nodes[MAX_NODE], *Root;
int _vCount, DfsCnt; struct Edge
{
Node *From, *To;
Edge *Next;
Edge() {}
}*_edges[MAX_EDGE];
int _eCount; Edge *NewEdge()
{
_eCount++;
return _edges[_eCount] ? _edges[_eCount] : _edges[_eCount] = new Edge();
} Edge *AddEdge(Node *from, Node *to)
{
Edge *e = NewEdge();
e->From = from;
e->To = to;
e->Next = from->Head;
from->Head = e;
return e;
} vector<Node*> Stack; void Init(int vCount)
{
_vCount = vCount;
_eCount = 0;
DfsCnt = 0;
Root = 1 + _nodes;
Stack.clear();
memset(_nodes, 0, sizeof(_nodes));
} void Dfs(Node *cur)
{
cur->DfsN = cur->Low = ++DfsCnt;
Stack.push_back(cur);
for (Edge *e = cur->Head; e; e = e->Next)
{
if (!e->To->DfsN)
{
Dfs(e->To);
cur->Low = min(cur->Low, e->To->Low);
}
else
cur->Low = min(cur->Low, e->To->DfsN);
}
if (cur != Root && cur->Low == cur->DfsN)
{
while (Stack.back() != cur)
Stack.pop_back();
Stack.pop_back();
}
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
freopen("c:\\noi\\source\\output.txt", "w", stdout);
#endif
int totNode, totEdge, uId, vId;
while (scanf("%d%d", &totNode, &totEdge) && (totNode || totEdge))
{
Init(totNode);
for (int i = 1; i <= totEdge; i++)
{
scanf("%d%d", &uId, &vId);
_nodes[uId].Id = uId;
_nodes[vId].Id = vId;
AddEdge(uId + _nodes, vId + _nodes);
}
Dfs(Root);
if (Stack.size()!=totNode)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}
HDU1269 有向图强连通分量的更多相关文章
- hdu1269(有向图强连通分量)
hdu1269 题意 判断对于任意两点是否都可以互相到达(判断有向图强连通分量个数是否为 1 ). 分析 Tarjan 算法实现. code #include<bits/stdc++.h> ...
- 有向图强连通分量的Tarjan算法
有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...
- 有向图强连通分量 Tarjan算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- 【转】有向图强连通分量的Tarjan算法
原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...
- 图的连通性:有向图强连通分量-Tarjan算法
参考资料:http://blog.csdn.net/lezg_bkbj/article/details/11538359 上面的资料,把强连通讲的很好很清楚,值得学习. 在一个有向图G中,若两顶点间至 ...
- 有向图强连通分量的Tarjan算法和Kosaraju算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- 算法笔记_144:有向图强连通分量的Tarjan算法(Java)
目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连 ...
- POJ3180(有向图强连通分量结点数>=2的个数)
The Cow Prom Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1451 Accepted: 922 Descr ...
- 有向图强连通分量的Tarjan算法及模板
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强联通(strongly connected),如果有向图G的每两个顶点都强联通,称有向图G是一个强联通图.非强联通图有向 ...
随机推荐
- JavaScript(基于react+dva)
变量声明 const 和 let:分别表示常量和变量 模板字符串 const user = 'world'; console.log(`hello ${user}`); // hello world ...
- retrofit post请求多文件,partMap用法
1. APIService 定义注解 @Multipart @POST("cyxx/Feedback/add.do") Observable<ResponseBody> ...
- 附加MySQL数据库的方法
下面讲解附加MySQL数据库的方法. (1)将“光盘\Code\04\Project\数据库”文件夹中的扩展名为.sql的文件拷贝到本地机器中. (2)在如图1所示的MySQL工作台界面中,单击Dat ...
- JDBC的详细使用
1.首先说一下需要用到的工具: ①我这里用的数据库是MySql5.6 ,MySql6.0开始被Oracle收购需要付费了,6.0以下版本免费. ②去Maven仓库下载JDBC的jar包 Maven仓库 ...
- 3B课程笔记分享_StudyJams_2017
昨晚才发现 Study Jams China的官方论坛也支持MarkDown,所以直接发在了那上面.http://www.studyjamscn.com/thread-21807-1-1.html
- 【PostgreSQL-9.6.3】如何实现非自动提交
我们在使用psql工具操作数据库时,事务是自动提交的.也就是说,当我们执行完一条insert或者delete语句后,在不输入commit情况下,这条语句也是提交的.如果不想自动提交,可以使用以下两种方 ...
- 【Linux】Vi中的各种命令
Ctrl+u:向文件首翻半屏: Ctrl+d:向文件尾翻半屏: Ctrl+f:向文件尾翻一屏: Ctrl+b:向文件首翻一屏: Esc:从编辑模式切换到命令模式: ZZ:命令模式下保存当前文件所做的修 ...
- Linux之tar.gz file
A tarball (tar.gz file) is compressed tar archive. The tar program provides the ability to create ta ...
- java编程题(一)
[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? //这是一个菲波拉契数列问题 p ...
- centos6 或者 centos7 重置遗忘的root密码
centos7 1.重启服务器. 2.在出现如下界面时,按“e”键,进入内核边界页面,如下图: 3.进入后,在“linux16”这行参数最后添加“rd.break”参数,输入完后,同时安装“ctrl” ...