题目:http://poj.org/problem?id=2762

题意:给出n个山洞,对于每个山洞,如果任意选择两点s,e,都满足s可以到达e或者e可以到达s,则输出Yes,否则输出No。

分析:实际上判断是否弱连通,所以首先强连通,然后缩点,对缩点形成的图最多只能有一个入度为0的点,如果有多个入度为

0的点,则这两个连通分量肯定是不连通的。缩点后形成的图形是一棵树,入度为0的点是这颗树的根,这棵树只能是单链,不

能有分叉,如果有分叉,则这些分叉之间是不可达的,所以就对这棵树进行DFS,如果是单链则是YES。

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 10005;
struct Edge
{
int to;
Edge *next;
};
Edge *map1[N],*map2[N];  //分别保存原图和缩点后的图
int dfn[N],low[N],stack[N],belong[N],indeg[N];
int index,scc_num,top;
bool tmp[N];
int result[N];
void Tarjan(int u)
{
dfn[u] = low[u] = ++index;
stack[++top] = u;
tmp[u] = true;
for(Edge *p = map1[u]; p; p = p->next) //枚举每一条边
{
int v = p->to;
if(!dfn[v])
{
Tarjan(v);  //dfs继续下找
low[u] = min(low[u],low[v]);
}
else if(tmp[v])
{
low[u] = min(low[u],dfn[v]);
}
}
if(low[u] == dfn[u]) //如果节点u是强连通分量的根
{
int t;
++scc_num;  //强连通分量个数加1
do
{
t = stack[top--];
tmp[t] = false;
belong[t] = scc_num;  //记录属于第几个强连通分量
}
while(t != u);
}
}
int Count(int n)
{
for(int i=1;i<=n;i++)
if(!dfn[i])
Tarjan(i);
return scc_num;
}
int Find() //在新图中找入度为0的点,如果只有一个就返回位置,否则返回0
{
int record;
int cnt = 0;
for(int i=1; i<=scc_num; i++)
{
if(indeg[i] == 0)
{
cnt++;
record = i;
}
}
if(cnt == 1) return record;
return 0;
}
bool TopSort()
{
int u,num = 0;
while(u = Find())
{
result[num++] = u;
indeg[u] = -1;
Edge *p = map2[u];
while(p)
{
indeg[p->to]--;
p = p->next;
}
}
if(num == scc_num) return true;
return false;
}
void Init()
{
index = 0;
top = 0;
scc_num = 0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(indeg,0,sizeof(indeg));
memset(tmp,false,sizeof(tmp));
memset(map1,NULL,sizeof(map1));
memset(map2,NULL,sizeof(map2));
memset(result,0,sizeof(result));
}
int main()
{
int T,m,n;
scanf("%d",&T);
while(T--)
{
Init();
scanf("%d%d",&n,&m);
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
Edge *p = new Edge();
p->to = b;
p->next = map1[a];
map1[a] = p;
}
int cnt = Count(n);
if(cnt == 1)
{
puts("Yes");
continue;
}
for(int i=1;i<=n;i++)
{
Edge *p = map1[i];
while(p)
{
if(belong[i] != belong[p->to])
{
indeg[belong[p->to]]++;
Edge *q = new Edge();
q->to = belong[p->to];
q->next = map2[belong[i]];
map2[belong[i]] = q;
}
p = p->next;
}
}
bool flag = false;
int ans = 0;
for(int i=1;i<=cnt;i++)
{
if(indeg[i] == 0)
ans++;
}
if(ans > 1) flag = false;
else if(TopSort()) flag = true;
if(flag) puts("Yes");
else     puts("No");
}
return 0;
}

POJ2762(判断无向图的弱连通)相关推荐

  1. 判断图有无环_判断无向图/有向图中是否存在环

    本文主要针对如何判断有向图/无向图中是否存在环的问题进行简单的论述. 一 无向图 1.利用DFS进行判断 利用DFS判断有向图是否存在环,是最为常用的一种方法,虽然这种方法很常用,但可参考的代码的实现 ...

  2. python找图里的环_python判断无向图环是否存在的示例

    暂时是一个手动设置无向图中的边,用一个二维数组表示,后面会改进为用户自己定义无向图的边. 学习python的新手,若大佬有解决的办法,希望不吝赐教 #无向图判断环是否存在 def dfs(u,fa): ...

  3. Python 判断无向图是否存在环

    代码实现 def has_cycle(G):"""判断无向图是否有环:param G: example {0: [1,2],1: [3], 2: []}:return:T ...

  4. 判断无向图是否有回路有四种方法

     一.无向图回路的判断 对于无向图,判断其是否有回路有四种方法,如下所示: 1.利用深度优先搜索DFS,在搜索过程中判断是否会出现后向边(DFS中,连接顶点u到它的某一祖先顶点v的边),即在DFS ...

  5. 判断无向图G是否是一颗树

    一个无向图是一颗树的条件是有n-1条边的连通图,n为图中顶点的个.边和顶点的数目是否满足条件可有图的信息直接判断,连通与否可以用遍历能否访问到所有顶点来判断. 结构体定义: #include<s ...

  6. 染色法判断无向图是否为二部图

    二分图 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的 ...

  7. python中判断无向图是否有环_数据结构与算法:17 图

    17 图 知识结构: 图1 知识结构 1. 图的基本概念与术语 1.1 图的定义 图由顶点集和边集组成,记为 . 顶点集:顶点的有穷非空集合,记为. 边集:顶点偶对的有穷集合,记为 . 边: 无向边: ...

  8. 有向图、无向图是否有环的判断

    今天在做数据库的调度冲突可串行性判别的程序,中间要用到有向图中环判定的问题,特摘录如下.这些算法和思想都是来自网上的,在此感谢原作者! 先介绍一下无向图的判断算法,这个比较简单: 判断无向图中是否存在 ...

  9. 求无向图的连通分量或有向图的强连通分量—tarjan()ccf高速公路

    概念定义: 在图论中,连通图基于连通的概念. 1. 连通(无向图): 若顶点Vi能通过路径到达Vj,那么称为Vi和Vj是连通的 对无向图:若从顶点Vi到顶点Vj有路径相连(当然从j到i也一定有路径), ...

最新文章

  1. Java 异常处理的 9 个最佳实践
  2. 未来十年是AI的黄金发展期
  3. bottle+jquery 前后端分离
  4. [机器学习]总结特征工程干货
  5. 老男孩shell实战读书笔记 (6-10章节)
  6. 枚举工具类 EnumUtils.java
  7. MySQL高可用之主备同步:javafor循环乘法表
  8. Struts2之异常处理
  9. Gogs代码托管系统安装配置手册
  10. Ingress.exe——今天你被监控了吗?
  11. PV-RCNN:Point-based与Voexl-based共同成就的高性能3D目标检测网络
  12. 计算机最最最底层的工作原理是怎么运行的
  13. 极坐标形式的复数计算器
  14. 背景是不规则图案css,CSS3 实现花式背景图案
  15. HTML语言剖析14:特殊字符
  16. 【Hadoop大数据分析与挖掘实战】(一)----------P19~22
  17. 分享创意个性古风剪影喜迎国庆PPT模板
  18. 6种不露脸的自媒体账号玩法,每一个变现都很强
  19. python编程培训多少钱-Python培训需要多少费用?
  20. 局域网找到计算机但无法访问磁盘,Win10系统不能访问局域网共享磁盘如何解决...

热门文章

  1. AnnotationConfigUtils 处理注解Bean 定义类中的通用注解
  2. AnnotationScopeMetadataResolver 解析作用域元数据
  3. 后台服务系统之dubbo架构
  4. Lambda表达式有参数有返回值的练习
  5. java进程优先级,跨平台方式改变java进程优先级
  6. 【java】动态绑定机制
  7. 函数计算机按键没反应,关于waitKey()函数按键无反应情况
  8. Ubuntu服务器上部署kodexplorer私有云盘
  9. 配置httpd虚拟主机
  10. DockOne微信分享(八十四):Docker在B站的实施之路