#include"stdio.h"//有向无权图
#include"stdlib.h"//采用邻接表存储图
structlinjienode//拓扑序列
{ //利用拓扑序列判断图中是否有环原理:
intlocation; //如果图中存在环,因为在寻找拓扑序列时,
structlinjienode * next; //入度的减少永远都无法破坏到该环
}; //也就是该环中的所有点的入度都不可能
structnode //减为0,即:环中的所有点都不可能进入
{ //拓扑序列中;使拓扑序列中的点永远都无法
intindu; //包含图中的所有点
structlinjienode * firstlinjie;
};
int main()
{
inta,i,j,k,nodeshu,bianshu,node1,node2,sum,sign,t;
structlinjienode * temp;
scanf("%d",&a);
for(i=0;i<a;i++)
{
sum=0;
scanf("%d %d",&nodeshu,&bianshu);
structnode nodezu[nodeshu];
for(j=0;j<nodeshu;j++)
{
nodezu[j].indu=0;
nodezu[j].firstlinjie=NULL;
}
for(j=0;j<bianshu;j++)
{
scanf("%d %d",&node1,&node2);
nodezu[node2-1].indu++;//对应点的入度也要自加
temp=(structlinjienode *)malloc(sizeof(structlinjienode));
temp->location=node2-1;
temp->next=NULL;
temp->next=nodezu[node1-1].firstlinjie;
nodezu[node1-1].firstlinjie=temp;
}
while(1)
{
sign=0;
for(j=0;j<nodeshu;j++)
{
if(nodezu[j].indu==0)
{
sign=1;//如果找到了就做个标记
sum++;//sum记录我们加入到拓扑序列中点的总数
nodezu[j].indu--;
for(temp=nodezu[j].firstlinjie;temp!=NULL;temp=temp->next)
{//把该点指向的所有点的入度数都减一
t=temp->location;
nodezu[t].indu--;
}
}
if(sign==1)
{//我们每次都从头开始到尾找一个入度为0的点
break;
}
}
if(sign==0)
{//如果所有点都遍历了,但还是没找到入度为0的点就退出while循环,不找了
break;
}
}
if(sum==nodeshu)//判断是否拓扑序列是否包含了图中所有点
{//如果包含了所有点,则说明改图不存在环,若没包含所有点则一定存在环
printf("Not A Loop Graph.\n");
}
else
{
printf("A Loop Graph.\n");
}
}
return0;
}
利用拓扑序列判断图中是否有环原理
最新推荐文章于 2023-12-04 08:54:06 发布