简单 的拓扑排序判断有向图是否有环,可是我wa了两天。
题意:
先给出n,m两个正整数,随后m行给出m个偏序关系,每次输入都得判断是否有环,是否能确定出n个元素的偏序关系,最后再判断是否能确定出n个元素的偏序关系。
大概思路:
该题首先有个优先级:
- 是否已经能根据以上条件能确定出唯一的偏序关系;
- 是否有环,有环则直接输出;
若条件1满足则直接输出偏序关系,若满足条件2则输出有环,若两者都不满足则继续执行,直到m行输入结束后,都不能判断的话输出无法判断。
核心代码如下:
int toposort()
{
res="";//记录答案
int flag=0,x=0;
memcpy(in,cnt,sizeof(cnt));
queue<int> que;
for(int i=0;i<n;i++)
if(!cnt[i])
que.push(i);
while(!que.empty())
{
if(que.size()>1)
flag=1;
int u=que.front();
que.pop();
res+=('A'+u);
for(int i=0;i<n;i++)
{
if(g[u][i])
{
in[i]--;
if(in[i]==0)
que.push(i);
}
}
}
if(res.size()!=n)//判断是否有环
return 0;
if(flag==1)//是否唯一
return -1;
return 1;
}
总结:
前几次wa在错误的判断是否有环上,以为只要有向图的初始状态有且只有一个入度为1的点就不会有环并存在唯一的拓扑序。后来看了几组测试数据才意识到问题的严重。然后就是聪明的 引入了一个vis数组来记录出现过的数据来进行排序。有点搬石头砸自己jio的意思,一旦引入了这个数组,判断是否有环的条件就变得复杂起来了。
还得注意每个输出后面的“.”。
正解应该是每次都把入度为0的点加入进队列中,因为未输入的点的入度初始为0所以未输入的点也会加入到队列中,这样就可以通过循环执行次数来判断是否有环。判断是否有唯一的排序时,用队列的大小来判断,若队列大小大于1说明有多个入度为0的点就不存在唯一的拓扑序。