zoukankan      html  css  js  c++  java
  • poj 1094 简单拓扑排序

    题意:

    给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。是典型的拓扑排序,但输出格式上确有三种形式:

       1.该字母序列有序,并依次输出;

       2.该序列不能判断是否有序;

       3.该序列字母次序之间有矛盾,即有环存在。

    分析:

    每次加入一条边,进行一次拓扑排序,判断是否可以唯一确定序列(唯一的话就是每次选点只有一个选择),是否矛盾(即有环,判断入队的数量即可,无环的话每个点都会入队一次)。




    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<stack>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    const int N=27;
    int in[N],inq[N]; //入度
    int g[N][N]; //判断是否有边
    int ans[N]; //保存排序结果
    int n,m;
    int toposort()
    {
        memcpy(inq,in,sizeof(in));
        queue<int>q;
        for(int i=0;i<n;i++)if(!inq[i])q.push(i);
        bool flag=0;
        int cnt=0;
        while(!q.empty()){
            if(q.size()>1)flag=1; //如果队列中有多个可选点,那么排序就不能唯一确定
            int t=q.front();q.pop();
            ans[cnt++]=t;
            for(int i=0;i<n;i++){
                if(g[t][i]){
                    inq[i]--;
                    if(!inq[i])q.push(i);
                }
            }
        }
        if(cnt!=n)return 0; //有环
        if(!flag)return 1; //序列唯一
        return 2; //拓扑排序
    }
    
    int main()
    {
        char s[10];
        while(~scanf("%d%d",&n,&m)&&(n+m)){
            memset(in,0,sizeof(in));
            memset(g,0,sizeof(g));
            int i;
            for(i=1;i<=m;i++){
                scanf("%s",s);
                in[s[2]-'A']++;
                g[s[0]-'A'][s[2]-'A']=1;
                int t=toposort();
                if(t==0){
                    printf("Inconsistency found after %d relations.
    ",i);
                    break;
                }
                else if(t==1){
                    printf("Sorted sequence determined after %d relations: ",i);
                    for(int j=0;j<n;j++)printf("%c",(char)('A'+ans[j]));
                    printf(".
    ");break;
                }
            }
            if(i>m)printf("Sorted sequence cannot be determined.
    ");
            else for(i=i+1;i<=m;i++)scanf("%s",s);
        }
        return 0;
    }
    


  • 相关阅读:
    TRAC-IK机器人运动学求解器
    机器人关节空间轨迹规划--S型速度规划
    机械臂运动学逆解(Analytical solution)
    Windows中读写ini文件
    glog日志库使用笔记
    V-rep学习笔记:切削
    机器人单关节力矩控制
    机器人中的轨迹规划(Trajectory Planning )
    DDD Example
    clearing & settlement
  • 原文地址:https://www.cnblogs.com/01world/p/5762857.html
Copyright © 2011-2022 走看看