• POJSorting It All Out (拓扑)


    题目链接

    题目大意:

    给定一定的数量的小于关系:

    1.如果发现环,输出从前几次就可以确定出现环

    2.如果能够确定唯一序列,输出。

    3.如果通过全部关系,还不能确定序列,则输出不能确定.

    分析:

    个人感觉难点在于判环上。

    1.如果每次都只能找到1个入度为0的点,并能确定序列,则该序列即为答案。

    2.如果每次查找时,发现两个及其以上的入度为0的点,则表明一定不能确定唯一序列(即存在环或者是不能确定)。如果可以确定一个任意序列,即表明还需要更多关系。如果继续查找下去,找不到入度为0的点,则存在环。 

    AC代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 500;
    const int INF = (1<<29);
    
    int n, m, indeg[maxn], S[maxn], top, mark;
    bool G[maxn][maxn], v[maxn];
    
    int toposort()
    {
        int deg[maxn], cn;
        bool vis[maxn], flag = true;
    
        top = 0;
        memcpy(deg, indeg, sizeof(deg));
        memset(vis, 0, sizeof(vis));
    
        for(int i=0; i<n; i++)
        {
            cn = 0;
    
            for(int k=0; k<n; k++) if(deg[k] == 0) cn++;            //计算入度为0的点的个数
    
            if(cn > 1) flag = false;                               //出现环或者不能确定唯一序列
            else if(cn == 0) break;                               //出现环
    
            int k;
            for(k=0; k<n; k++) if(deg[k] == 0) break;
            S[top++] = k;
            deg[k]--;
            for(int j=0; j<n; j++) if(G[k][j]) deg[j]--;
        }
    
        if(cn == 0) return -1;      //
        if(mark < n || !flag) return 0;      //不能判断
        else return 1;   //拓扑成功
    }
    
    int main()
    {
        char c1, c2;
        int flag, num;
      //  freopen("my.txt", "r", stdin);
        while(scanf("%d %d", &n, &m) == 2)
        {
            if(n == 0 && m == 0) break;
    
            memset(indeg, 0, sizeof(indeg));
            memset(G, false, sizeof(G));
            memset(v, false, sizeof(v));
    
            flag = 0;
            mark = 0;
    
            for(int i=0; i<m; i++)
            {
                getchar();
                scanf("%c<%c", &c1, &c2);
    
                if(!G[c1-'A'][c2-'A']) {
                    G[c1-'A'][c2-'A'] = true;
                    indeg[c2-'A']++;
                }
    
                //mark用来标记当前已经出现的字母的个数
                if(!v[c1-'A']) { v[c1-'A'] = true; mark++; }
                if(!v[c2-'A']) { v[c2-'A'] = true; mark++; }
    
    
                int res;
                if(flag == 0) {
                    res = toposort();
    
                    if(res == -1) {
                        flag = -1;
                        num = i;
                    } else if(res == 1) {
                        num = i;
                        flag = 1;
                    }
                }
            }
    
            if(flag == 1) {
                printf("Sorted sequence determined after %d relations: ", num+1);
                for(int i=0; i<top; i++)
                {
                    putchar(S[i]+'A');
                }
                printf(".
    ");
            }
            else if(flag == 0) printf("Sorted sequence cannot be determined.
    ");
            else printf("Inconsistency found after %d relations.
    ", num+1);
        }
    
        return 0;
    }
  • 相关阅读:
    纪念Google Reader—Google Reader的最后一天
    SlickEdit 18.0 版本发布 同时更新破解文件
    Linux设置中文的man手册
    Android按钮单击事件的五种实现方式
    使用VBS脚本语音朗读文字
    JavaGUI设置windows主题外观
    EL表达式
    自己封装的一个Ajax小框架
    微信公众号清除内存缓存
    墨刀编辑微信端 原型设计
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3254260.html
Copyright © 2020-2023  润新知