HDU 3594 Cactus 有向图判强连通及每条边是否仅属于一个环
来源:互联网 发布:大数据合作协议 编辑:程序博客网 时间:2024/05/06 16:21
判断是不是一个环环间以点相连的有向图。
Cactus的意思是仙人掌,不形象啊。
大概思路:
从起点0开始搜,搜到环就把环mark掉(环与搜索路径相连的点不mark,且从此点开始继续搜)。搜完后把所有搜到的点依次作为起点作如此搜索。如果搜到了之前mark的点(搜到起点不算)则说明有边存在于两个环。复杂度O(E)吧=。=
伪代码:
bool 函数(){
1、把起点0放入一个queue(stack也可以,无所谓,仅起储存作用,不过为了和后面的stack区分,就放入queue吧,实际上代码里也是stack:pstk);
2、当queue不为空,拿出front元素,记为start,从此点开始深搜,queue为空跳第7句;
3、搜索时要记录每个点当前搜索的边,下次从这点开始搜时就从这点的下一条边开始,那执行就可能会发现当前点已经没有边可搜了,那就看这个点是否是start点,不是的话返回0(说明不是强连通图,易证),是的话将其退栈,将其mark(事实上如果这点不是0的话,它必定已经被mark了),执行第2句;
4、把搜索的当前点放入stack,instk[u]=1,如果此点被mark了且不是start,返回0(说明有边存在于两个环,可证);
5、如果搜到一个不在stack内的点,那就放入stack内,同时instk[u]=1,再同时把u放入队列,从这点开始搜,跳回第3句;
6、否则,这个点就是在stack内,把栈顶到此元素之间的所有点退栈(除了刚搜到的这个点),同时将其mark,从这点开始搜,继续从第3句开始执行;
7、扫描所有点,如有点没被mark,那就连弱连通也不是,返回0(代码中没加这句也过了,说明数据给出的都至少是弱连通的,懒得加了),否则返回1。
}
#include<iostream>#include<queue>using namespace std;struct Edge{ int u,v,next;};Edge edge[50000];int N,head[20000],en;void insert(int u,int v){ edge[en].u=u;edge[en].v=v;edge[en].next=head[u]; head[u]=en++;}void get_data(){ memset(head,-1,sizeof(head)); en=0; int a,b; scanf("%d",&N); while(scanf("%d%d",&a,&b),a||b){ insert(a,b); }}int cur[20000],pstk[20000],psn,stk[20000],sn;bool mark[20000],instk[20000];bool run(){ int i; for(i=0;i<N;i++)cur[i]=head[i];//初始化当前的边 memset(mark,0,sizeof(mark)); memset(instk,0,sizeof(instk)); sn=psn=0; pstk[psn++]=0; int u,v,start; while(psn){ start=u=pstk[--psn];//第2句 if(cur[u]==-1)continue; while(true){//----第3句---- if(cur[u]==-1){ if(u==start){ sn--; mark[u]=1; break; }else return 0; }//-------------- stk[sn++]=u;instk[u]=1; for(;cur[u]!=-1;){ v=edge[cur[u]].v;cur[u]=edge[cur[u]].next;//把当前边设为下一条,为下次这一点的搜索作准备 if(v!=start&&mark[v])return 0;//第4句 if(!instk[v]){//第5句 pstk[psn++]=v; u=v;break; }else{//第6句 while(stk[sn-1]!=v){ mark[stk[sn-1]]=1; sn--; } u=v; } } } }//第7句 =。= return 1;}int main(){ int t; scanf("%d",&t); while(t--){ get_data(); if(run())printf("YES\n"); else printf("NO\n"); } return 0;}
- HDU 3594 Cactus 有向图判强连通及每条边是否仅属于一个环
- HDU 3594(Cactus)----判断强连通的图中每条边是不是只在一个环内
- hdu 3594 强连通判断一条边是否只属于一个环
- hdu 3594 (求强连通图+判断没条边是否只属于一个环)
- HDU 3594 Cactus 强连通
- HDU 3594 Cactus 【强连通】
- HDU3594 Cactus 强连通 判断一条边是否只在一个环内
- HDU 3594 Cactus(强连通)
- HDU 3594 Cactus 判断一条边是否在多个环内
- HDU 3594 Cactus 强连通判断仙人掌图
- LA 4287,HDU 2767 求有向图强连通分量个数和各节点属于哪个分量
- 算法导论22.5-7 给出一个算法确定一个有向图是否为半连通
- 邻接矩阵 有向图 判断是否有环 是否连通 DFS C实现~
- 判断强联通图中每条边是否只在一个环上(hdu3594)
- 判断一个有向图是否有环
- 判断一个有向图是否有环
- 判断有向图是否有环及拓扑排序
- 判断有向图是否有环及环中元素
- 经不起考验的感情
- WPFLinkerNode第二弹:可编辑的序列系统。
- Java报表软件不带参程序数据集
- Flex模块化程序开发
- 男人的真话胜似、女人的口红
- HDU 3594 Cactus 有向图判强连通及每条边是否仅属于一个环
- 平淡、一生的追求
- 过往云烟~如梦随风飘!!!
- 字符集,代码页和字体
- 使用.NET存储XML数据
- 汉字转拼音(C#)
- 使用.NET存储XML数据
- 安卓,IOS“机”林之争,谁才是“机”林盟主?
- UnixSocketV1Chap3SocketBasic