zoukankan      html  css  js  c++  java
  • 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.
    ",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(".
    ");
    70                 ok=1;                   //得到答案就ok=1
    71             }
    72         }
    73         if(!ok)                 //如果不矛盾也没答案,就输出这个
    74         {
    75             printf("Sorted sequence cannot be determined.
    ");
    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.
    ",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(".
    ");
    73                 ok=1;
    74             }
    75         }
    76         if(!ok)                 //如果不矛盾也没答案,就输出条件不够
    77             printf("Sorted sequence cannot be determined.
    ");
    78     }
    79     return 0;
    80 }
    View Code
     
  • 相关阅读:
    Python3组合数据类型(元组、列表、集合、字典)语法
    tkinter模块常用参数(python3)
    python3的正则表达式(regex)
    QC的使用简介
    Linux常用命令
    Linux中jdk的安装和环境变量的配置
    大道至简阅读笔记07
    大道至简阅读笔记06
    大道至简阅读笔记05
    个人工作总结10
  • 原文地址:https://www.cnblogs.com/Giaogiaogiao123/p/12643795.html
Copyright © 2011-2022 走看看