POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)
2016-01-24 18:25
507 查看
这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径。
方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变成DAG。
现在问题就变成,如何判断DAG是否是单连通图——用拓扑排序——如果拓扑排序过程中出现1个以上入度为0的点那就不是单连通图,因为有2个入度0的点,那这两个点肯定都无法到达对方。
另外,注意题目没说给的图是连通的!。。
方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变成DAG。
现在问题就变成,如何判断DAG是否是单连通图——用拓扑排序——如果拓扑排序过程中出现1个以上入度为0的点那就不是单连通图,因为有2个入度0的点,那这两个点肯定都无法到达对方。
另外,注意题目没说给的图是连通的!。。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define MAXN 1111 #define MAXM 6666 struct Edge{ int u,v,next; }edge[MAXM]; int NE,head[MAXN]; void addEdge(int u,int v){ edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u]; head[u]=NE++; } int belong[MAXN],bn,stack[MAXN],top; bool instack[MAXN]; int dn,dfn[MAXN],low[MAXN]; void dfs(int u){ dfn[u]=low[u]=++dn; stack[++top]=u; instack[u]=1; for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(dfn[v]==0){ dfs(v); low[u]=min(low[u],low[v]); }else if(instack[v]){ low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ int v; ++bn; do{ v=stack[top--]; belong[v]=bn; instack[v]=0; }while(u!=v); } } int deg[MAXN]; bool toposort(){ queue<int> que; for(int i=1; i<=bn; ++i){ if(deg[i]==0) que.push(i); } if(que.size()>1) return 0; while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(--deg[v]==0) que.push(v); } if(que.size()>1) return 0; } return 1; } int main(){ int t,n,m,a,b; scanf("%d",&t); while(t--){ NE=0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); while(m--){ scanf("%d%d",&a,&b); addEdge(a,b); } top=bn=dn=0; memset(instack,0,sizeof(instack)); memset(dfn,0,sizeof(dfn)); for(int i=1; i<=n; ++i){ if(dfn[i]==0) dfs(i); } int tmp=NE; NE=0; memset(head,-1,sizeof(head)); memset(deg,0,sizeof(deg)); for(int i=0; i<tmp; ++i){ int u=belong[edge[i].u],v=belong[edge[i].v]; if(u==v) continue; addEdge(u,v); ++deg[v]; } if(toposort()) puts("Yes"); else puts("No"); } return 0; }
相关文章推荐
- HDU 3966 Aragorn's Story(树链剖分)
- django1.8.2 建站实现分页显示功能
- 【Usaco 2010 NOV Gold】奶牛的图片
- hdu1847 Good Luck in CET-4 Everybody!
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
- HDU-4982-Goffi and Squary Partition【贪心】【构造】
- HMM学习笔记—002--维特比算法(viterbi algorithm)
- Atom插件go-plus的离线安装
- OC基础之Category,Extension,Protocol
- uva11292 - The Dragon of Loowater (贪心)
- gitlab和Django实现push自动更新
- gitlab和Django实现push自动更新
- gitlab和Django实现push自动更新
- 张江男的逆袭,我如何使用leangoo提升团队效率
- BZOJ 1419: Red is good|期望Dp
- 在visual studio 2013下使用Google Test
- 1419: Red is good 概率与期望 DP
- 搭建go语言idea开发环境
- connect-mongo:Error: Connection strategy not found
- 谷歌应用商店Google Play即将重返中国