Sorting It All Out

这是一道拓扑排序的问题。

感觉到自己的脑子像是生锈了一样!

题目描述:


做这道题的时候,题目的意思纠结了好久。三种情况之间的关系,纠结了好久。后来wa了一次,两个原因,一个是因为输出排序的时候那个小点点忘记打印上去了,另一个是Inconsistency和cannot be determined的优先级搞错了。总之,就是题目读得很模糊,题意理解得不够清晰。下面就仔细得把这道题的要求写出来:

给定一些关系,其中关系的对象就是大写字母,没有其他。让你根据这些关系求解;输出的要求分为三种:

有特定的顺序的(这里特定是指唯一的顺序,可以确定的唯一排序)

图中有环的

无法确定唯一顺序的

*注意,这三个要求都是建立在按照给出条件顺序来执行的,也就是比如第一个例子,到第4个表达式就可以确定了,后面条件表达式会造成什么样的结果忽略不计,然后第2个是到第2个条件表达式发现了矛盾,最后一个是当条件都全部给出后,还是无法确定唯一顺序,所以可以写出优先级——>(特定顺序==矛盾)> 无法确定!这个顺序很重要


然后,如何判断有矛盾:用队列的话就是当队列为空的时候,还有元素没有被遍历到

如何判断不唯一:在队列算法进行到任何时候,当出现两个以上入度为0的点

如何判断序列排好:没有矛盾&&从未出现两个或两个以上的点入度为0&&全部的点都被遍历过(0-n)


反思:第一:要认真分析题目 第二:要仔细检查输出 第三:刷题和思考是不可以间断的 

最后,加油!


核心代码:

int n, m, num, ax, mp[30][30], en[30], ren[30];
char ans[30];
bool vis[30];
bool circle, cannot;

int Toposort(int tn)
{
    queue<int> Q; cannot = false;
    memset(ans, 0, sizeof(ans));
    memset(vis, 0, sizeof(vis));
    memset(ren, 0, sizeof(ren));
    for ( int i = 1; i <= tn; ++i ) if ( en[i] == 0 ) Q.push(i);
    //printf("%d\n", Q.size());
    if ( Q.size() > 1) cannot = true;
    if ( Q.size() == 0 ) return 0;
    int tmp = 1;
    while( !Q.empty() )
    {
        int x = Q.front(); Q.pop();
        int num = 0; vis[x] = true;
        ans[tmp-1] = x - 1 +'A';
        //printf("%c\n", ans[tmp]);
        for ( int i = 1; i <= n; ++i )
        {
            if ( mp[x][i] && !vis[i] ) {
                ren[i]++;
                if ( en[i] == ren[i] )
                {
                    num++;
                    if ( num > 1 ) cannot = true;
                    Q.push(i);
                    tmp++;
                }
            }
        }
    }
    for ( int i = 1; i <= tn; ++i ) if ( !vis[i] ) return 0;
    if ( cannot ) return -1;
    if ( tn == n ) return n;
    return tmp;
}

int main()
{
    while (scanf("%d%d", &n, &m) != EOF && ( n != 0 || m != 0 ))
    {
        bool flag = true;
        int tn = 0;
        memset(mp, 0, sizeof(mp));
        memset(en, 0, sizeof(en));
        for ( ax = 1; ax <= m; ++ax )
        {
            getchar();
            char u, v, op;
            scanf("%c%c%c", &u, &op, &v);
            int tu = u-'A'+1, tv = v-'A'+1;
            if ( tn < tu ) tn = tu;
            if ( tn < tv ) tn = tv;
            mp[tu][tv] = 1;
            en[tv]++;
            if ( flag )
            {
                int Topo = Toposort(tn);
                if ( Topo == 0 ) {
                    flag = false;
                    printf("Inconsistency found after %d relations.\n", ax);
                }
                else if ( Topo == n ) {
                    flag = false;
                    printf("Sorted sequence determined after %d relations: ", ax);
                    printf("%s.\n", ans);
                }
            }
        }
        if ( flag ) printf("Sorted sequence cannot be determined.\n");
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值