【判定弱连通】==【tarjan求scc + 缩点+拓扑】
来源:互联网 发布:windows10改mac地址 编辑:程序博客网 时间:2024/05/23 01:59
给你一个N个点M条边的有向图,判断该图是否为弱连通。
思路:首先tarjan求SCC + 缩点,建成新图后,可以证明的是,新图必定有入度为0的点。在保证每个点都有边相连的前提下,我们进行一次拓扑排序,在这个过程中若遇到不符合弱连通的条件即跳出。反之一直处理到队列为空,这时说明该图为弱连通图。
遵循条件
一:新图不能有多于1个的入度为0的点,这是保证每个点都有边相连。
二:在拓扑排序遍历点u的过程中,若去掉与u相关的边后出现多于1个的入度为0的点,说明这些点只能由u到达,而它们之间不存在可达路径。这时不满足弱连通,跳出。
(其实就是 缩点后的新图,一定要有一个 确切的序列 —这样才说明图是一个弱连通)
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<iostream>#include<vector>using namespace std;const int MAXN= 10010+10;struct Edge { int from,to,next;}edge[60000+10];int head[MAXN],top;int n,m;void init(){ memset(head,-1,sizeof(head)); top=0;}void addedge(int a,int b){ Edge e={a,b,head[a]}; edge[top]=e;head[a]=top++;}void getmap(){ int a,b; while(m--){ scanf("%d%d",&a,&b); addedge(a,b); }}int low[MAXN],dfn[MAXN];int scc_cnt,sccno[MAXN];stack<int>S;int Instack[MAXN];vector<int>G[MAXN];int dfs_clock;void tarjan(int now,int par){ low[now]=dfn[now]=++dfs_clock; S.push(now);Instack[now]=1; for(int i=head[now];i!=-1;i=edge[i].next){ Edge e=edge[i]; if(!dfn[e.to]){ tarjan(e.to,now); low[now]=min(low[now],low[e.to]); }else if(Instack[e.to]) low[now]=min(low[now],dfn[e.to]); } if(low[now]==dfn[now]) { scc_cnt++; for(;;){ int nexts=S.top();S.pop();Instack[nexts]=0; sccno[nexts]=scc_cnt; if(nexts==now) break; } }}void find_cut(int le,int ri){ memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(Instack,0,sizeof(Instack)); memset(sccno,0,sizeof(sccno)); dfs_clock=scc_cnt=0; for(int i=le;i<=ri;i++){ if(!dfn[i]) tarjan(i,-1); }}int in[MAXN];void suodian(){ for(int i=1;i<=scc_cnt;i++) { in[i]=0;G[i].clear(); } for(int i=0;i<top;i++){ Edge e=edge[i]; int now=sccno[e.from]; int nexts=sccno[e.to]; if(now!=nexts){ G[now].push_back(nexts); in[nexts]++; } }}queue<int>Q;bool topo(){ while(!Q.empty()) Q.pop(); int num=0; for(int i=1;i<=scc_cnt;i++){ if(!in[i]) { Q.push(i); num++; if(num>1) return false; } } int k=0; while(!Q.empty()){ int now=Q.front();Q.pop();num=0;k++; for(int i=0;i<G[now].size();i++){ int v=G[now][i]; if(--in[v]==0){ Q.push(v); num++; if(num>1) return false; } } } return k==scc_cnt; // 可能缩点后的新图本身就不是连通的}void solve(){ find_cut(1,n); suodian(); if(scc_cnt==1) puts("Yes"); else puts(topo()?"Yes":"No");}int main(){ int t;cin>>t;while(t--){ cin>>n>>m; init(); getmap(); solve(); } return 0;}
阅读全文
0 0
- 【判定弱连通】==【tarjan求scc + 缩点+拓扑】
- Going from u to v or from v to u? 【判定弱连通】=【tarjan求scc+ 缩点+topo】
- poj 2762 Going from u to v or from v to u? 【判断图是否为弱连通】 【tarjan求SCC + 缩点 + 拓扑排序】
- hdoj 1827 Summer Holiday 【有向图 连通最少的点来间接连通所有点】 【tarjan求 SCC + 缩点】
- Summer Holiday 【有向图中连通最少的点来使其整个图 连通的】+【tarjan求SCC +缩点】
- hdoj 3836 Equivalent Sets 【tarjan 求SCC + 缩点】
- 不是图论 【tarjan求scc】+【缩点】
- Tarjan求强连通(缩点)
- Tarjan求强连通分量 缩点
- hdoj 3072 Intelligence System 【SCC缩点 求连通所有SCC的费用】
- poj 3648 Wedding 【2-sat 经典建图 输出一组可行解 好题】 【tarjan求SCC + 缩点 + 拓扑排序 + 染色】
- 不完全浅析Tarjan求强连通分量(SCC)
- 【POJ1236】【tarjan】【SCC强连通】
- poj 2553 (tarjan求强连通分量+缩点)
- [笔记]关于tarjan求连通分量 & 缩点
- tarjan算法缩点&&求强连通分量【转载】
- hdoj Summer Holiday 1827 (强连通分量 求最少连通多少点从而连通所有点) arjan求SCC+缩点 好题
- poj 2375 Cow Ski Area 【SCC缩点 求最少增加几条边使图强连通】
- 传奇名将孔蒂接掌尤文图斯 再续前缘
- 南海!南海!
- 哲科 帕齐尼 阿奎罗 到桑切斯 ——为什么都跟尤文图斯抢人?
- 李娜2:0斯齐亚沃尼 法网夺冠 改写历史
- 尤文-阿奎拉尼在等 皮尔洛为什么离开AC米兰 ……
- 【判定弱连通】==【tarjan求scc + 缩点+拓扑】
- 足球100人 马拉多纳、贝利领衔
- 南海问题争端再起 中越互相指责【转】
- python笔记(9)----异常
- 【转】迭戈·马拉多纳——想到什么就说什么、直肠子
- 〖英格兰〗 大卫·贝克汉姆——记忆中的第一个足球明星~当年中分帅气的发型
- CSU-1593 丹麦海峡
- Excel的25个知识~边看边操作
- Google+无法征服Facebook十大原因【转】