拓扑排序POJ 1094

这题就是拓扑排序,但是能确定的情形必须是拓扑序列唯一。做法是在读边的时候 ,读完一条边后就调用topsort函数,如果通过topsort函数能确定出现环,则矛盾,或者存在了把所有 n个字母都包括进去了的唯一拓扑序列。就可以输出结果,以后就不调用topsort函数了。但是注意剩下的数据要读完,当读完所有的边上述两种情况都还没有出现,就可以输出不能确定了

我是这样做的,在做拓扑排序时,先把入度为0的顶点入栈,该顶点入度设为-1(这样就不会重复入栈)如果出现两入度为0,可以知道不存在唯一拓扑序列了,别急,要接着做拓扑排序,从栈中 pop出元素,所有是该顶点后继的顶点的入度减一,再找入度为0的顶点入栈,直至栈空,判断会不会出现环,排除出现矛盾的情形,这样才不遗漏啊````

这题让我很无语,一直WA,本来我是自己手打的那什么Sorted sequence  blabla一长串,想试试自己会不会打错,事实上,我一个一个的比对了,自我感觉没什么错的地方啊,连空格都认真看了,然后我修改了一下程序,再复制粘贴原网页上语句的又交了一次,然后就A了,事实证明,自己打也许真的很坑爹啊。。。。。

 下面贴代码:

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 int n,m;
  4 int sn ;  //关系描述中出现过多少不同字母
  5 char l[30];
  6 struct  node//顶点
  7 {
  8     int num; //出边数目
  9     int count; //入度,当入过栈后,入度为-1
 10     int temp;  //用来坐复制板
 11     int edge[50]; //出边的终点
 12     bool visited; //顶点是否是出现关系描述中
 13 } p[30];
 14 int Topsort()
 15 {
 16     int mystack[30];
 17     bool ist = true ;
 18     int cur = 0;
 19     int cnt = 0;
 20     int re = 0;//同时出现两个入度为0也算是不确定的
 21     for(int k = 0; k<n; k++)
 22         p[k].temp = p[k].count;
 23     for(int i=0; i< n; i++)
 24     {
 25         if(p[i].visited && p[i].temp==0)
 26         {
 27             mystack[cur++] = i;
 28             l[ cnt++] = i+'A';
 29             p[i].temp--;
 30             re++;
 31         }
 32     }
 33     if(re > 1) ist = false;
 34     while(cur != 0)
 35     {
 36         cur--;
 37         int t = mystack[cur];
 38         for(int j = 0; j< p[t].num; j++)
 39             p[p[t].edge[j]].temp--;
 40         re = 0;
 41         for(int i=0; i< n; i++)
 42         {
 43             if(p[i].visited && p[i].temp == 0)
 44             {
 45                 mystack[cur++] = i;
 46                 l[cnt++] = i+'A';
 47                 p[i].temp--;
 48                 re++;
 49             }
 50         }
 51         if(re > 1) ist = false;
 52     }
 53     l[cnt] = '\0';
 54     if(cnt < sn) return 2; //出现矛盾
 55     else if(cnt < n || !ist) return 0; //表示不确定
 56     else if(cnt == n ) return 1;//可以确定拓扑排序
 57 }
 58 int main()
 59 {
 60 //    freopen("in1.cpp","r",stdin);
 61     while(~scanf("%d%d",&n,&m))
 62     {
 63         bool flag = false;  //有确定结果了
 64         if(n== 0 && m == 0) break;
 65         for(int i=0; i<n; i++)
 66         {
 67             p[i].temp = 0;
 68             p[i].count = 0;
 69             p[i].num = 0;
 70             p[i].visited = false;
 71         }
 72         sn = 0;
 73         for(int i=0; i<m; i++)
 74         {
 75             char a[5];
 76             scanf("%s",a);
 77             if(!flag)
 78             {
 79                 int u = a[0] - 'A';
 80                 int v = a[2] - 'A';
 81                 p[u].edge[p[u].num++] = v;
 82                 p[v].count++;
 83                 if(!p[u].visited)
 84                 {
 85                     p[u].visited = true;
 86                     sn++;
 87                 }
 88                 if(!p[v].visited)
 89                 {
 90                     p[v].visited = true;
 91                     sn++;
 92                 }
 93                 int der = Topsort();
 94                 if(der == 2)
 95                 {
 96                     printf("Inconsistency found after %d relations.\n",i+1);
 97                     flag = true;
 98                 }
 99                 else if(der == 1 )
100                 {
101                     printf("Sorted sequence determined after %d relations: %s.\n",i+1,l);
102                     flag = true;
103                 }
104             }
105         }
106         if(!flag) printf("Sorted sequence cannot be determined.\n");
107     }
108     return 0;
109 }
原文地址:https://www.cnblogs.com/allh123/p/2989708.html