poj1094_toposort

题意:给你一些大写字母间的偏序关系,然后让你判断能否唯一确定它们之间的关系,或者所给关系是矛盾的,或者到最后也不能确定它们之间的关系。

分析:

用拓扑排序:

1.拓扑排序可以用栈来实现,每次入栈的是入度为0的节点。

1.拓扑排序的结果一般分为三种情况:1、可以判断 2、有环出现了矛盾 3、条件不足,不能判断.

2.这道题不仅需要判断这三种情况,而且还要判断在处理第几个关系时出现前两种情况,对于本道题来说三种情况是有优先级的。前两种情况是平等的谁先出现先输出谁的相应结果,对于第三种情况是在前两种情况下都没有的前提下输出相应结果的.

网上对于这道题的错误提示:

1.本题顺序:

a.先判有没有环,有环就直接输出不能确定;

b.如果没有环,那么就看会不会有多种情况,如果有多种情况就再读下一行;如果全部行读完还是有多种情况,就是确定不了;

c.如果最后没有环,也不存在多种情况(即每次取出来入度为零的点只有一个),那么才是答案;

2.有答案就先出答案,不管后面的会不会矛盾什么的;

3.如果在没有读完所有输入就能出答案,一定要把剩下的行都读完。

代码:

View Code
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <stack>
 5 using namespace std;
 6 //toposort的三种情况
 7 //188K 0MS
 8 const int N=27;
 9 int n,m;
10 int graph[N][N],indegree[N],list[N];
11 
12 int toposort(int n)
13 {
14     int in[N];
15     memcpy(in,indegree,sizeof(indegree)); //复制入度数组,以免对主函数中的indegree有影响
16     stack<int> s;
17     int i;
18     for(i=0;i<n;i++)
19         if(!in[i])
20             s.push(i);//所有入度为0的点入栈,如果这些点多于1的话,序列不确定
21     int flag=0;
22     int t,j=0;
23     while(!s.empty())
24     {
25         if(s.size()>1)
26             flag=1;    //序列不确定
27         t=s.top();
28         s.pop();
29         list[j++]=t;   //记录出栈的数字
30         for(i=0;i<n;i++)
31             if(graph[t][i])
32                 if(--in[i]==0)
33                     s.push(i);//入度为0的点入栈
34     }
35     if(j!=n)//不能拓扑排序,即有环
36         return 1;
37     else if(flag==1)//有多种排序方式,不能唯一确定
38         return 2;
39     return 0;//序列能够被唯一确定
40 }
41 
42 int main()
43 {
44     int determined,inconsistency;
45     int i,j,res;
46     char a,b;
47     while(scanf("%d%d",&n,&m) && n!=0 && m!=0)
48     {
49         getchar();
50         determined=0;
51         inconsistency=0;
52         memset(graph,0,sizeof(graph));
53         memset(indegree,0,sizeof(indegree));
54         for(i=1;i<=m;i++)
55         {
56             scanf("%c<%c",&a,&b);
57             getchar();
58             if(!determined && !inconsistency)
59             {
60                 if(graph[b-'A'][a-'A']==1)//存在反向边,则发现矛盾
61                 {
62                     inconsistency=1;
63                     printf("Inconsistency found after %d relations.\n",i);
64                     continue;
65                 }
66                 if(graph[a-'A'][b-'A']==0)
67                 {
68                     graph[a-'A'][b-'A']=1;
69                     indegree[b-'A']++;
70                 }
71                 res=toposort(n);//toposort
72                 if(res==0)//序列能够被唯一确定
73                 {
74                     printf("Sorted sequence determined after %d relations: ",i);
75                     for(j=0;j<n;j++)
76                         printf("%c",list[j]+'A');
77                     printf(".\n");
78                     determined=1;
79                 }
80                 else if(res==1)//不能拓扑排序,即有环,发现矛盾
81                 {
82                     printf("Inconsistency found after %d relations.\n",i);
83                     inconsistency=1;
84                 }
85             }
86 
87         }
88         if(!determined && !inconsistency)//既没有唯一确定,也没发现矛盾(有环),即不能确定
89             printf("Sorted sequence cannot be determined.\n");
90     }
91     return 0;
92 }

tju oj 1159

 

 

 

 

 

 

posted @ 2012-08-23 10:48 pushing my way 阅读(...) 评论(...) 编辑 收藏