POJ

题意描述:给定前n个字母的关系描述,根据输入的m组描述(类似A<B),判断能否唯一确定前n个字母的顺序,或者看能否出现矛盾,并且要求输出得出结论时共需用到前面多少组数据,或者最终不能确定顺序。

分析:每次添加一组关系就进行一次拓扑排序,看能否判断关系,或者得出矛盾;如果是不确定的关系就继续添加直到数据用完,或者得出结论。关于判定关系是不是唯一确定的只需要看拓扑排序过程中,每次去掉一个入度为0的点之后剩下的入度为0的点是否唯一,如果不是的话最终得出来的关系就是不唯一的。

代码:

#include <iostream>
#include <sstream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <string>
#include <map>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define esp 1e-6
#define pb push_back
#define mp(a, b) make_pair((a), (b))
#define in  freopen("in.txt", "r", stdin);
#define out freopen("out.txt", "w", stdout);
#define print(a) printf("%d
",(a));
#define bug puts("********))))))");
#define stop  system("pause");
#define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define inf 0x0f0f0f0f
using namespace std;
typedef long long  LL;
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef vector<pii,int> VII;
typedef vector<int>:: iterator IT;
const int maxn = 30;
VI g[maxn];
int du[maxn], L[maxn], vis[maxn];
int n, m, ok;
bool check(void)
{
    int ct = 0;
    for(int i = 0; i < n; i++)
        if(!du[i] && !vis[i])
        {
            ct++;
            if(ct > 1) return false;
        }
    return true;
}
bool toposort(void)
{
    memset(du, 0, sizeof(du));
    for(int i = 0; i < n; i++)
        for(int j = 0; j < g[i].size(); j++)
            du[g[i][j]]++;
    ok = check();
    queue<int> q;
    for(int i = 0; i < n; i++)
        if(!du[i]) q.push(i);
    int tot = 0;
    while(!q.empty())
    {
        int x = q.front();
        L[tot++] = x;
        vis[x] = 1;
        q.pop();
        for(int j = 0; j < g[x].size(); j++)
        {
            int t = g[x][j];
            du[t]--;
            if(!du[t]) q.push(t);
        }
        if(ok) ok = check();
    }
    return tot == n;
}
int main(void)
{
    while(scanf("%d%d", &n, &m), n||m)
    {
        int flag = 0;
        int k;
        char s[10];
        for(int i = 0; i < maxn; i++) g[i].clear();
        for(k = 1; k <= m; k++)
        {
            ok = 1;
            scanf("%s", s);
            int u, v;
            u = s[0] - 'A';
            v = s[2] - 'A';
            g[u].pb(v);
            memset(vis, 0, sizeof(vis));
            if(!toposort())
            {
                flag = 1;
                printf("Inconsistency found after %d relations.
", k);
                break;
            }
            else if(ok)
            {
                flag = 1;
                printf("Sorted sequence determined after %d relations: ", k);
                for(int i = 0; i < n; i++)
                    putchar(L[i] + 'A');
                puts(".");
                break;
            }
        }
        for(int i = k+1; i <= m; i++)
            scanf("%s", s);
        if(!flag && k > m)
            puts("Sorted sequence cannot be determined.");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/rootial/p/3331703.html