已知有向图G=(V,E),具有n个顶点,以邻接表的形式存储。请设计一个算法,判断图G中是否存在有向回路。
解题思路:ggt使用dfs,在遍历过程中,若下一个邻接结点时已访问的,则证明有回路,否则无回路。
出了好几年的dfs啦!!一定要记住!!
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int MAXN=100;
typedef struct ArcNode//边表结点
{
int adjvex;
ArcNode *nextvex;
};
typedef struct Vnode//顶点表结点
{
int data;
ArcNode *firstvex;
};
typedef struct Graph//图
{
Vnode adjlist[MAXN];
int n;
int e;
}*graph;
graph g=(graph)malloc(sizeof(Graph));
void build(graph g)//用邻接表存储图
{
printf("n,e==");
scanf("%d%d",&g->n,&g->e);
for(int k=1;k<=g->n;k++)
{
g->adjlist[k].data=k;
g->adjlist[k].firstvex=NULL;
}
printf("输入边边的from和to:\n");
int i,j;
for(int k=1;k<=g->e;k++)
{
scanf("%d%d",&i,&j);
ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextvex=g->adjlist[i].firstvex;
g->adjlist[i].firstvex=p;
}
}
void print(graph g)//输出邻接表存储的图
{
for(int k=1;k<=g->n;k++)
{
printf("%d ",g->adjlist[k].data);
ArcNode *p=g->adjlist[k].firstvex;
while(p!=NULL)
{
printf("%d ",p->adjvex);
p=p->nextvex;
}
printf("\n");
}
}
int visit[100];//标记数组
int flag=0;//标记是否有回路
void dfs(graph g,int v)
{
if(flag==1) return;//若有回路则返回
visit[v]=1;//标记当前正在访问的结点
ArcNode *p= g->adjlist[v].firstvex;//p为当前结点的邻接结点
while(p!=NULL)
{
if(visit[p->adjvex]==1)//若与当前结点的邻接结点状态为被访问过,则说明有回路
{
flag=1; return;
}
else dfs(g,p->adjvex);
p=p->nextvex;
}
visit[v]=0;
}
int main()
{
build(g);
print(g);
memset(visit,0,sizeof(visit));
dfs(g,1);
if(flag==1) printf("有回路\n");
else printf("无回路\n");
return 0;
}
/*测试数据
5 5
1 2
1 3
2 4
3 4
4 5
*/