仙林鼎山游乐园(有向图判断环)

仙林鼎山游乐园 时间限制(普通/Java):1000 MS/ 3000 MS 运行内存限制 : 65536 KByte 总提交 : 369 测试通过 : 100

题目描述

端午节到来,sed投资建设的仙林鼎山游乐园开业了。整个园区拥有许多游乐场,有多个入口和多个出口,游乐场之间铺设小路相连。端午节来游乐园的人实在太多,sed发布规定:游乐场之间的小路为单行道。但游乐场太多,工作人员常常将指示方向的标志牌放错方向,导致游客在游乐园又回到游览过的地方。请sed解决这个问题,按照现有的标志牌指示的方向,,判断游客在一次行程中是否有可能回到游览过的地方。

输入

第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括:

l 第1行给出两个整数n、e,2≤n≤50,1≤e≤1225,n表示游乐场的数目,游乐场分别用,e表示所有游乐场之间路径数。

l e行,每1行给出两个整数,分别表示两个游乐场的序号,给出了它们之间的单行道。

输出

对于每个测试用例:

l 输出YES或NO,表示按照现有的标志牌指示的方向,游客在一次行程中是否有可能回到游览过的地方。

样例输入

2210133011220

样例输出

NOYES

题目来源

“IBM南邮杯”团队赛2009 【深紫】

题目地址:?&method=showdetail&id=1119

本题的实质:判断有向图中是否存在环。

这里有三种做法:

①拓扑排序

原理:若节点未全部输出前,已经不存在入度为0的节点,则说明此有向图有环。

#include<stdio.h>#include<string.h>int g[51][51],InDegree[51],Stack[51];//存储有向图、入度和建立栈 int main(){int T,n,e,i,j,top=-1,tmp;scanf("%d",&T);while(T–){memset(g,0,sizeof(g));memset(InDegree,0,sizeof(InDegree));memset(Stack,0,sizeof(Stack));scanf("%d%d",&n,&e);while(e–){scanf("%d%d",&i,&j);g[i][j]=1;InDegree[j]++;}for(i=0;i<n;i++)if(InDegree[i]==0){Stack[++top]=i;InDegree[i]=51; //删除进栈节点 }for(i=0;i<n;i++){if(top==-1){printf("YES\n");break;}else{tmp=Stack[top–];for(j=0;j<n;j++)if(g[tmp][j])InDegree[j]–;}for(j=0;j<n;j++)if(InDegree[j]==0){Stack[++top]=j;InDegree[j]=51;}}if(i==n)printf("NO\n");}return 0;}

②Floyd(转载自)

原理:找出所有边的连通关系,再判断边<i,j>和边<j,i>是否为True

#include <cstdio>#include <cstring>int const MAX = 55;int E[MAX][MAX], n, e;void Floyd(){for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)for(int k = 0; k < n; k++)if(E[i][j] && E[j][k])E[i][k] = true;}bool check(){for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)if(E[i][j] && E[j][i])return true;return false;}int main(){int T;scanf("%d", &T);while(T–){int x, y;memset(E, 0, sizeof(E));scanf("%d %d", &n, &e);for(int i = 0; i < e; i++){scanf("%d %d", &x, &y);E[x][y] = true;}Floyd();if(check())printf("YES\n");elseprintf("NO\n");}}

③DFS

原理:见代码注释

#include<stdio.h>#include<string.h>int g[51][51],vis[51];//vis表示某节点的访问状态:未被访问,被访问过,此节点的//后续节点都被访问 void DFS(int p,int n,int *tag){vis[p]=-1;for(int i=0;i<n;i++){if(g[p][i]!=0){if(vis[i]==-1){*tag=1;return;}else if(vis[i]==0)DFS(i,n,tag);}}vis[p]=1;//p的后续都访问完,后面再有节点指向p也没用,因为它不在深度遍历的路径上 }int main(){int T,n,e,i,j,tag;scanf("%d",&T);while(T–){tag=0;memset(g,0,sizeof(g));memset(vis,0,sizeof(vis));scanf("%d%d",&n,&e);while(e–){scanf("%d%d",&i,&j);g[i][j]=1;}for(i=0;i<n;i++)if(vis[i]==0)DFS(i,n,&tag);if(tag==0)printf("NO\n");else printf("YES\n");}return 0;}

也许不是自己该去发挥的地方,还是让自己到最适合自己战斗的方面去吧!勇敢的接受自己的失败,

仙林鼎山游乐园(有向图判断环)

相关文章:

你感兴趣的文章:

标签云: