http://acm.hdu.edu.cn/showproblem.php?pid=3594

判断给定的图是否是强连通的,并且每条边都只属于一个连通分量.

判断强连通只需要判断缩点之后顶点数是否为1即可,

然后在缩点的过程中,如果已经产生环,并且当前结点的父节点还有父节点,则必定有多个环,

最后还要判断每个结点都要只属于一个联通分量,否则不符合要求.

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout); using namespace std;
#define N 20100
//N为最大点数
#define M 50100
//M为最大边数
int n, m;//n m 为点数和边数 struct Edge{
int from, to, nex;
bool sign;//是否为桥
}edge[M<<];
int head[N], edgenum;
void add(int u, int v){//边的起点和终点
Edge E={u, v, head[u], false};
edge[edgenum] = E;
head[u] = edgenum++;
}
//DNF[i]表示遍历到第i点时,是第几次dfs
//Low[u] 表示 以u点为父节点的 子树 能连接到 [栈中] 最上端的点 的DFN值(换句话说,是最小的DFN,因为最上端的DFN是最小的嘛)
int DFN[N], Low[N], Stack[N], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)
int taj;//连通分支标号,从1开始
int Belong[N];//Belong[i] 表示i点属于的连通分支
bool Instack[N],flag;
vector<int> bcc[N]; //标号从1开始 void tarjan(int u ,int fa){
DFN[u] = Low[u] = ++ Time ;
Stack[top ++ ] = u ;
Instack[u] = ; for (int i = head[u] ; ~i ; i = edge[i].nex ){
int v = edge[i].to ;
if(DFN[v] == -)
{
tarjan(v , u) ;
Low[u] = min(Low[u] ,Low[v]) ;
if(DFN[u] < Low[v])
{
edge[i].sign = ;//为割桥
}
}
else if(Instack[v])
{
Low[u] = min(Low[u] ,DFN[v]) ;
if(DFN[v]!=Low[v]) flag=; //父节点还不是根节点
}
}
if(Low[u] == DFN[u]){
int now;
taj ++ ; bcc[taj].clear();
do{
now = Stack[-- top] ;
Instack[now] = ;
if(Belong[now]!=-) flag=; //每个节点都要只属于一个联通分量
Belong [now] = taj ;
bcc[taj].push_back(now);
}while(now != u) ;
}
} void tarjan_init(int all){
memset(DFN, -, sizeof(DFN));
memset(Instack, , sizeof(Instack));
memset(Belong,-,sizeof(Belong));
top = Time = taj = ;
for(int i=;i<=all;i++)if(DFN[i]==- )tarjan(i, i); //注意开始点标!!!
}
vector<int>G[N];
int du[N];
void suodian(){
memset(du, , sizeof(du));
for(int i = ; i <= taj; i++)G[i].clear();
for(int i = ; i < edgenum; i++){
int u = Belong[edge[i].from], v = Belong[edge[i].to];
if(u!=v)
{
G[u].push_back(v), du[v]++;
// printf("%d %d\n",u,v);
}
}
}
void init(){memset(head, -, sizeof(head)); edgenum=;}
int main()
{
//Read();
int t,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
flag=;
while()
{
scanf("%d%d",&a,&b);
if(a==&&b==) break;
add(a+,b+);
}
tarjan_init(n);
suodian(); if(taj==&&flag==) puts("YES");
else puts("NO");
}
return ;
}

最新文章

  1. Jsoup做接口测试
  2. spring-事务管理
  3. Python :open文件操作,配合read()使用!
  4. 元组tuple
  5. 演示get、post请求如何算sn,算得sn如何使用
  6. vs 2012 + OPenCV 2.4.8 配置
  7. 自动化测试工具Selenium和QTP的比较
  8. 织梦DedeCMS网站地图模板
  9. publish over ssh
  10. CentOS7 部署 tomcat
  11. [.Net Core] 简单使用 Mvc 内置的 Ioc(续)
  12. rpm 安装、卸载软件命令 ——以nginx为例
  13. 检索html页自生成&amp;nasp;标签,并替换为空(即去掉空格)
  14. 用c#查询各快递物流信息
  15. elasticsearch数据过期删除处理
  16. Node学习笔记---初识Node
  17. SceneControl+AE+鼠标滚轮缩放
  18. MDX示例:求解中位数、四分位数(median、quartile)
  19. Java获取资源的路径
  20. 20172330 2017-2018-1 《Java程序设计》第十周学习总结

热门文章

  1. $Codeforces\; Round\; 504\; (Div.2)$
  2. Linux 特殊权限位简介
  3. 学习Python第一天,命令很多跟Linux还有脚本语言相似。
  4. python 基础知识汇总—— if else while continue
  5. LeetCode(137) Single Number II
  6. java读写串口数据
  7. Java-确定被加载类的路径
  8. vue.js+element-ui
  9. CSS里总算是有了一种简单的垂直居中布局的方法了
  10. Java 正则表达式详解---https://www.jb51.net/article/16829.htm