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;
}
原文地址:https://www.cnblogs.com/tanhehe/p/3254260.html