/*该题被博客里标记为中等题,30分钟内1A,掌握了算法就简单了,单向连通图判定,单向连通图缩点
后必然唯一存在出度为0的点和入度为0的点,并且从入度为0的点出发,可以遍历所有点后到达出度为0点
(一条长链),(容易反证),所以缩点后,我重新建图(以前觉得重新建图好麻烦,现在看来SO easy),
,对新有向无环图,从入度为0的点做dfs(回溯时要标记回来,因为要所有dfs路线),有一条深度到达
强连通分支数即为yes,反之no*/
#include<iostream> //297MS, 1A,简单题。
#include<vector>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int n;int m;
const int MAX=1001;
vector<vector<int> >edges(MAX); //原图
vector<vector<int> >newedge(MAX);//缩点后图
int visited[MAX]; //原图tarjan
int low[MAX];
int dfn[MAX];
bool mark[MAX]; //新图dfs标记
int Strongly_connected_branch[MAX]; //并为一个强连通,标记为1.2.3...
int num;int times;
stack<int>s;
bool instack[MAX];
int ind[MAX]; //入度数组
void tarjan(int u)
{
low[u]=dfn[u]=times++;
instack[u]=1;
s.push(u);
int len=edges[u].size();
for(int i=0;i<len;i++)
{
int v=edges[u][i];
if(visited[v]==0)
{
visited[v]=1;
tarjan(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&low[u]>dfn[v]) //有向图,要问是否在栈中,后向边,V为U某个祖先
{
low[u]=dfn[v];
}
}
if(dfn[u]==low[u]) //在一个SCC
{
num++;int temp;
do
{
temp=s.top();
instack[temp]=0;
s.pop();
Strongly_connected_branch[temp]=num;
} while(temp!=u);
}
}
bool is_no;
void dfs(int u,int depth) //新图的dfs
{
if(depth==num)is_no=true;
int len=newedge[u].size();
for(int i=0;i<len;i++)
{
int v=newedge[u][i];
if(mark[v]==0)
{
mark[v]=1;
dfs(v,depth+1);
mark[v]=0;
}
}
}
void readin()
{
scanf("%d%d",&n,&m);
int from,to;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&from,&to);
edges[from].push_back(to);
}
}
void initialize() //初始化
{
is_no=num=times=0;
for(int i=0;i<=n;i++)
{
ind[i]=0;
mark[i]=instack[i]=low[i]=dfn[i]=visited[i]=0;
edges[i].clear();
newedge[i].clear();
Strongly_connected_branch[i]=-1;
}
}
void solve()
{
for(int i=1;i<=n;i++)
if(visited[i]==0)
{
visited[i]=1;
tarjan(i);
}
for(int i=1;i<=n;i++) //重新建图,不在同一个SCB的边留下即可。
{
int len=edges[i].size();
for(int j=0;j<len;j++)
{
int v=edges[i][j];
if(Strongly_connected_branch[v]!=Strongly_connected_branch[i]) //注意用SCB序号作代表元(新节点)来重新建图
{
ind[Strongly_connected_branch[v]]++;
newedge[Strongly_connected_branch[i]].push_back(Strongly_connected_branch[v]);
}
}
}
int is_0ind;
for(int i=1;i<=num;i++) //找到入度为0的点,做起点dfs
{
if(ind[i]==0)is_0ind=i;
}
mark[is_0ind]=1;
dfs(is_0ind,1);
if(is_no)printf("Yes\n");
else printf("No\n");
}
int main()
{
int tcase;
scanf("%d",&tcase);
while(tcase--)
{
initialize();
readin();
solve();
}
return 0;
}

poj2767,单向连通图判定,缩点+重新建图+新图DFS的更多相关文章

  1. POJ2762 单向连通图(缩点+拓扑排序

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19552 ...

  2. SCC重新建图

    Tarjan或Kosaraju算法[对每个点归类belong]求出SCC之后,对num_scc个SCC重新建图,针对不同问题,考虑重边的问题. //************************** ...

  3. poj 2762 Going from u to v or from v to u?(强连通分量+缩点重构图+拓扑排序)

    http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit:  ...

  4. hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

  5. HDU 1827 Summer Holiday(tarjan求强连通分量+缩点构成新图+统计入度+一点贪心思)经典缩点入门题

    Summer Holiday Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs

    题意如标题所述, 先无向图缩点,统计出每个bcc权,建新图,然后一遍dfs生成树,标记出每个点(新图)以及其子孙的权值之和.这样之后就可以dfs2来枚举边(原图的桥),更新最小即可. 调试了半天!原来 ...

  7. BZOJ 1179 抢掠计划atm (缩点+有向无环图DP)

    手动博客搬家: 本文发表于20170716 10:58:18, 原地址https://blog.csdn.net/suncongbo/article/details/81061601 https:// ...

  8. 判断单向连通图(拓扑排序+tarjan缩点)

    题意: 给你一个有向图,如果对于图中的任意一对点u和v都有一条从u到v的路或从v到u的路,那么就输出’Yes’,否则输出’No’. 理解:当出现两个及以上入度为0的点(有一个就可能是别人到它,有两个的 ...

  9. React Native 重新建项目遇到的一些问题

    1.基本上一句话,就是本地的node太旧了,跟不上React_Native的节奏,所以需要更新node,但是单纯的更新node丫丫竟然不让我跟,因为是用Homebrew来管理的,所以先update了下 ...

随机推荐

  1. RxJava尝试取代Handler初探

    在之前的一篇文章中,我们探究了RxJava的使用方法,详细请看https://www.cnblogs.com/yanyojun/p/9745675.html 根据扔物线大神的描述,如果用一个词来概括R ...

  2. C# 图片打印杂谈

    日常开头水一下,看了下上次博客,一年零八天了,啧啧,奢侈. 最近这个工作挺满意的,是我想要的发展方向,后续要做机器学习,现在得先把公司之前堆积的问题解决了. 谈人生到此结束,还是说正题吧.(感觉这标题 ...

  3. SQLite – GROUP BY

    SQLite - GROUP BY SQLite GROUP BY子句中使用与SELECT语句的合作安排相同的数据组. 在GROUP BY子句之前一个SELECT语句的WHERE子句,先于ORDER ...

  4. (转)编码剖析Spring装配基本属性的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52856465 上回我们已经讲到了Spring依赖注入的第一种方式,现在我们来详解第二种方式,须 ...

  5. System类与两种输入流

    1.System类对I/O的支持系统输出System.out.println 是利用了I/O流的模式完成的.实际是打印流PrintStream对象 System类中定义了三个操作的常量 1.标准/系统 ...

  6. 众皓网络(T 面试)

    1.你们项目中哪里用到了Redis? 2.Redis中存储的数据,你们什么时候进行更新? 3.你用过消息队列吗? 4.你写的这个微服务项目拆分成了几个服务? 5.SpringCloud项目怎么部署的?

  7. 请简述HTML和XHTML最重要的4点不同?

    请简述HTML和XHTML最重要的4点不同? 不同: XHTML要求正确嵌套                   XHTML 所有元素必须关闭                   XHTML 区分大小 ...

  8. C-基础:数组名与取地址符&

    指出下面代码的输出,并解释为什么.(不错,对地址掌握的深入挖潜) main() { ]={,,,,}; ); printf(),*(ptr-)); } 输出:2,5     *(a+1)就是a[1], ...

  9. 第1节 flume:9、flume的多个agent串联(级联)

    3.两个agent级联 需求分析: 第一个agent负责收集文件当中的数据,通过网络发送到第二个agent当中去,第二个agent负责接收第一个agent发送的数据,并将数据保存到hdfs上面去 第一 ...

  10. 连接mysql 2003 Can't connect to Mysql on 'xxx'(10061)

    备份 cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak 修改 vim /etc/mysql/my.cnf 在[mysqld]下修改为bind-address=0.0 ...