题意: 判断是不是强连通图 ,同时每一条边必须只能在一个环里

思路:之前我的强连通用的全是双深搜,结果题目的第二个要求很难判断,一开始写了三个深搜加上并查集,结果越写越乱,其实就是在判断一个边是否只在一个环内搞不定,后来看了下网上的代码,用的全是tarjan,没办法了,又学习了一下tarjan算法,学完后发现这个算法不错,比双深搜快一倍的时间吧,他的时间复杂度是O(n + m) n是点m是边,tarjan算法的运行步骤为第二问的解决提供了条件,其中的stack,low,dfn配合的很好,我们要开一个数组记录搜索路径,然后当我们搜到一个点发现他被搜过同时他还在stack中的话,我们直接通过路径数组原路返回到他,把路上所有的点的次数都加1(开个数组记录次数),如果发现有大于1的直接就NO了,还有就是点有一个点的次数不要加1,就是查找路径的第一个点的上一个点,也是路径中的最后一个点(因为是环),这样就ok了.

#include<stdio.h>
#include<string.h>
#include<stack>
                               
#define N_node 25000 + 1000
#define N_edge 55000 + 1000

using namespace std;

typedef struct
{
   int to ,next;
}STAR;

STAR E[N_edge];
int list[N_node] ,tot;
int mer[N_node];
int count[N_node];
int DFN[N_node] ,LOW[N_node];
int Index ,num ,okk;
int instack[N_node];
stack<int>st;

void add(int a ,int b)
{
   E[++tot].to = b;
   E[tot].next = list[a];
   list[a] = tot;
}

int minn(int x ,int y)
{
   return x < y ? x : y;
}

void merge(int e ,int s)
{
   while(mer[s] != e)
   {
      count[s] ++;
      if(count[s] >= 2)
      {
         okk = 1;
         return ;
      }
      s = mer[s];
   }
}

void Tarjan(int s)
{
   if(okk) return;
   DFN[s] = LOW[s] =  Index ++;
   st.push(s);
   instack[s] = 1;
   for(int k = list[s] ;k ;k = E[k].next)
   {
      int to = E[k].to;
      if(!DFN[to])
      {
         mer[to] = s;
         Tarjan(to);
         LOW[s] = minn(LOW[to] ,LOW[s]);
      }
      else if(instack[to])
      {
         LOW[s] = minn(DFN[to] ,LOW[s]);
         merge(to ,s);
         if(okk) return;       
      }
   }
   if(LOW[s] == DFN[s])
   {
      num ++;
      if(num > 1) okk = 1;   
      while(1)
      {
         int v = st.top();
         st.pop();
         instack[v] = 0;
         if(v == s) break;
      }
   }
   return ;
}
 
int main ()
{
   int t ,i ,n ,a ,b;
   scanf("%d" ,&t);
   while(t--)
   {
      scanf("%d" ,&n);
      memset(list ,0 ,sizeof(list));
      memset(instack ,0 ,sizeof(instack));
      memset(DFN ,0 ,sizeof(DFN));
      memset(LOW ,0 ,sizeof(LOW));
      memset(count ,0 ,sizeof(count));
      for(i = 0 ;i < n ;i ++)mer[i] = i;
      while(!st.empty()) st.pop();
      tot = Index = 1 ,num = 0;
      while(scanf("%d %d" ,&a ,&b) && a + b)
      {
         add(a ,b);
      }
      okk = 0;
      for(i = 0 ;i < n ;i ++)
      {
         if(okk) break;
         if(DFN[i]) continue;
         Tarjan(i);
      }
      if(okk) printf("NO\n");
      else printf("YES\n");
   }
   return 0;
}

hdu3594 强连通 tarjan相关推荐

  1. POJ 1236 Network of Schools(强连通 Tarjan+缩点)

    POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意:  给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...

  2. 强连通 Tarjan

    强连通: 在一个有向图中任意两点都可以相互到达,那么称这两个点是强连通的,如果一个有向图G的任意两个顶点都强连通,那么称G为一张强连通图,对于一张图,它的极大强连通子图称为强连通分量 Tarjan T ...

  3. 强连通 Tarjan+Kosaraju (HDU1269+hdu3836)

    什么是强连通分量(StronglyConnected Component)(或者,被称为强连通子图,Strongly Connected Subgraph)? 首先需要明白的是,强连通分量只可能存在于 ...

  4. 强连通Tarjan NYOJ 120 校园网络

    校园网络 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 南阳理工学院共有M个系,分别编号1~M,其中各个系之间达成有一定的协议,如果某系有新软件可用时,该系将允许一些其 ...

  5. Popular Cows POJ - 2186(tarjan算法)+详解

    题意: 每一头牛的愿望就是变成一头最受欢迎的牛.现在有 N头牛,给你M对整数(A,B),表示牛 A认为牛B受欢迎.这种关系是具有传递性的,如果 A认为 B受欢迎, B认为 C受欢迎,那么牛 A也认为牛 ...

  6. 算法与数据结构简单启蒙,我当年学习算法走过的坑

    1.碎碎念 我的算法启蒙来自于紫书算法竞赛入门经典,但是不得不说从语言过度到算法,紫书并不是一个很好的开始.当时整本书除了数学和图论其实是看完了的,但真的有印象的大约只有暴力枚举法中枚举排列,子集生成 ...

  7. 萌新在线模板--keyboarder_zsq

    好像马上就要出去打铁了QAQ,所以是不是要做个模板带过去也玩一玩? 那就做吧... 标题就设为萌新模板吧...各种萌新讲解对吧.... 快速输入 template <class T> in ...

  8. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)...

    转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2194090a96bbed2db1351de8.html 基本概念: 1.割点:若删掉某点后,原连通图 ...

  9. 解题报告:luogu P2341 受欢迎的牛(Tarjan算法,强连通分量判定,缩点,模板)

    题目链接:洛谷 受欢迎的牛 基本上算是一道模板题 根据题意,如果有环,意味着这个环里的牛都互相喜欢 我们可以先求出环,然后把每一个环都看作一个点,这样整个图就变成了一个DAG(有向无环图) 看有几个点 ...

最新文章

  1. 大年初一,今年的春晚你看了吗?
  2. php生成gz文件,如何使用PHP创建.gz文件?
  3. java中的字符串相关知识整理
  4. 【图论】【Kosaraju】刻录光盘(ssl 2344)
  5. jpa findone怎么用_Jpa VS MyBatis,你用哪个?
  6. python访问k8s的api_python过滤 Kubernetes api数据
  7. Yii2 源码分析 - 入口文件执行流程
  8. centos 虚拟机 使用串口_在VMware虚拟机环境下安装CentOS 7操作系统
  9. Android逆向基础笔记—初识逆向
  10. caffe常用小工具
  11. android手机charles证书下载
  12. js通过身份证计算年龄
  13. linux下oracle登陆建表,Oracle建表过程初学
  14. 国内三大常见核心期刊体系简介——CSSCI、CSCD与中文核心期
  15. 微信小程序发送服务通知(模板消息)前后端实现代码附效果图
  16. 必备知识---TCP三次握手和四次挥手以及SSL四次握手
  17. 北京外企 外服控股:人服国企借道资产重组上市,发 力数字化谋新篇
  18. 100块钱买100只鸡的故事
  19. 【imx6ull-alientek-emmc】linux交叉编译环境 + 内核编译
  20. 墨西哥城新机场 | 一座来自未来的机场

热门文章

  1. Apache Spark机器学习.1.7 机器学习工作流示例
  2. Windows下 MySQL命令 常用操作
  3. 找到一本不错的Linux电子书,附《Linux就该这么学》章节目录。
  4. C#强化系列:HttpModule,HttpHandler,HttpHandlerFactory简单使用
  5. Java Nashorn--Part 3
  6. dispatch_async 与 dispatch_get_global_queue
  7. SQL Server 数据库状态选项
  8. 嵌入式SQL程序的VC+SQL server 2000实现的环境配置
  9. 【邮件】生产数据库优化第一步:重建索引
  10. Centos更换阿里云源