Sorting It All Out (拓扑排序) poj1094

题目地址:http://www.fjutacm.com/Problem.jsp?pid=1516

题目:
用小于号"<"来定义两元素之间的关系,并于一个没有重复元素的有序上升序列 从小到大地排列这些元素。
比如说,序列A,B,C,D意味着A<B;B<C;C<D。
在这个问题里,我们会给你一组形如"A<B"的关系,询问你有序序列的合法性或其本身。
输入
输入有多组数据。
每一组数据由其第一行的2个正整数n,m开始。
第一个正整数n代表有n个元素需要排序(2<=n<=26),这些元素一定是按照字母表顺序,从第一个字母(A)开始的n个大写字母。
第二个正整数m代表有m个关系将会在这组数据中被给出。
接下来有m行输入,每一行输入包含3个字符:一个大写字母,一个"<"符号,另一个大写字母。
所有输入的字母不会超出n规定下的,字母表中的字母范围。
当输入的n=m=0时,代表输入结束。
输出
对于每一组数据,输出有一行。输出必须也必定是以下三种情况之一:
Sorted sequence determined after X relations: YYYY.
[友情翻译:有序序列在给出X个条件后可以成立: YYYY.]
Sorted sequence cannot be determined.
[友情翻译:无法建立有序序列]
Inconsistency found after X relations.
[友情翻译:在给出X个关系后出现矛盾]
X是一个整数。
YYYY是当前条件下的有序数列,之间没有分隔符与空格。
样例输入
4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0
样例输出
Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.
 
 
一开始题目就看的不是很懂,从https://blog.csdn.net/weixin_43987810/article/details/96021102这里看了题目的翻译搞懂。
题目其他比较正常,主要是需要求到给出的第几个关系可以求出序列或者出现矛盾,所以就需要每次输入一个关系就运算一次。
网上找的代码都是直接用数组做的,我习惯用vector和queue,就自己写篇博客记一下。
 
 
用数组做的:
 1 #include<stdio.h>
 2 #include<string.h>
 3 using namespace std;
 4 
 5 int map[30][30];                 //map标记是否有关系
 6 int in[30],n,m;                  //in为入度
 7 int ans[30];                    //储存答案序列
 8 int Tp()
 9 {
10     int temp[30];               //展示存放入度
11     int num;                    //num表示零入度定点数
12     int pos;                    //存放零入度定点
13     int cnt=0;
14     int flag=1;                 //flag=1表示有序,flag=-1表示条件不足
15     for(int i=1;i<=n;i++)
16         temp[i]=in[i];          //备份
17     for(int i=1;i<=n;i++)       //需要全图遍历
18     {
19         num=0;
20         for(int j=1;j<=n;j++)
21         {
22             if(temp[j]==0)         //入度为0
23             {
24                 num++;              //零入度点+1
25                 pos=j;              //存放零入度点
26             }
27         }
28         if(num==0)                  //无零入度点则有环
29             return 0;
30         else if(num>1)              //零入度点不止一个则条件不足
31             flag=-1;
32         temp[pos]=-1;               //令此零入度点入度为-1,后面就不找他了
33         ans[cnt++]=pos;              //把这个点插入答案序列里
34         for(int j=1;j<=n;j++)
35         {
36             if(map[pos][j])           //他的小弟都入度-1
37                 temp[j]--;
38         }
39     }
40     return flag;
41 }
42 int main(void)
43 {
44     while(~scanf("%d %d",&n,&m))
45     {
46         if(n==0&&m==0) break;
47         memset(map,0,sizeof(map));
48         memset(in,0,sizeof(in));
49         int ok=0;
50         for(int i=1;i<=m;i++)
51         {
52             char s[5];
53             scanf("%s",&s);
54             if(ok) continue;            //已经完成就continue
55             int a=s[0]-64,b=s[2]-64;
56             map[a][b]=1;                //标记
57             in[b]++;                     //b入度+1
58             int flag=Tp();
59             if(flag==0)                 //flag=0表示矛盾了
60             {
61                 printf("Inconsistency found after %d relations.\n",i);
62                 ok=1;                   //得到答案就ok=1
63             }
64             else if(flag==1)            //flag=1表示序列已经成立了,输出序列
65             {
66                 printf("Sorted sequence determined after %d relations: ",i);
67                 for(int j=0;j<n;j++)
68                     printf("%c",ans[j]+64);
69                 printf(".\n");
70                 ok=1;                   //得到答案就ok=1
71             }
72         }
73         if(!ok)                 //如果不矛盾也没答案,就输出这个
74         {
75             printf("Sorted sequence cannot be determined.\n");
76         }
77     }
78     return 0;
79 }
View Code

 

用vector和queue做的:

 1 #include<stdio.h>
 2 #include<queue>
 3 #include<vector>
 4 #include<string.h>
 5 using namespace std;
 6 
 7 int in[30],n,m;                 //in存入度
 8 vector<int> head[30];               //存与该点有关的小弟
 9 vector<int> ans;
10 int Tp()
11 {
12     queue<int> q;                  //定义一个队列暂存序列
13     ans.clear();                    //清空ans
14     int flag=1;                     //flag=1表示有序,flag=-1表示条件不足
15     int temp[30];                   //暂时存放入度
16     for(int i=1;i<=n;i++)
17         temp[i]=in[i];                 //备份
18     for(int i=1;i<=n;i++)
19     {
20         if(temp[i]==0)              //寻找零入度点并插入队列
21             q.push(i);
22     }
23     while(!q.empty())               //把队列里的点放入ans
24     {
25         if(q.size()>1)              //如果q队列里的点不止一个,说明条件不足
26             flag=-1;                 //令flag=-1,但不能直接return ,因为还要继续判断是否矛盾了
27         int x=q.front();              //拿出队列中的点
28         q.pop();                        //队列中删去
29         ans.push_back(x);               //存入ans
30         for(int j=0;j<head[x].size();j++)       //遍历与该店有关的小弟
31         {
32             if(--temp[head[x][j]]==0)           //令其入度-1并判断之后是否为零,是插入队列中
33                 q.push(head[x][j]);
34         }
35     }
36     if(ans.size()!=n)               //若ans中的点不足n,则表示有环,关系矛盾了
37         return 0;
38     return flag;
39 }
40 
41 int main(void)
42 {
43     while(~scanf("%d %d",&n,&m))
44     {
45         if(n==0&&m==0) break;
46 
47         int ok=0;                       //该清空的都清空一下
48         memset(in,0,sizeof(in));
49         for(int i=1;i<=n;i++)
50             head[i].clear();            //这个忘了清wa了一次
51 
52         for(int i=1;i<=m;i++)
53         {
54             char s[5];
55             scanf("%s",s);
56             if(ok) continue;            //已经完成就continue
57             int a=s[0]-64,b=s[2]-64;        
58             head[a].push_back(b);           //存一下a点的小弟
59             in[b]++;                        //b入度+1
60 
61             int flag=Tp();
62             if(flag==0)                 //有环
63             {
64                 printf("Inconsistency found after %d relations.\n",i);
65                 ok=1;
66             }
67             else if(flag==1)            //得到有序答案了
68             {
69                 printf("Sorted sequence determined after %d relations: ",i);
70                 for(int j=0;j<ans.size();j++)
71                     printf("%c",ans[j]+64);
72                 printf(".\n");
73                 ok=1;
74             }
75         }
76         if(!ok)                 //如果不矛盾也没答案,就输出条件不够
77             printf("Sorted sequence cannot be determined.\n");
78     }
79     return 0;
80 }
View Code

 

 

 

posted @ 2020-04-06 19:33  Len北  阅读(119)  评论(0编辑  收藏  举报