AcWing 排序

AcWing 排序

Description

  • 给定 n 个变量,m 个不等式。

    不等式之间具有传递性,即若 A>B 且 B>C ,则 A>C。

    判断这 m 个不等式是否有矛盾。

    若存在矛盾,则求出 t 的最小值,满足仅用前 t 个不等式就能确定不等式之间存在矛盾。

    若无矛盾,则判断这 m 个不等式是否能确定每一对变量之间的关系。

    若能,则求出 t 的最小值,满足仅用前 t 个不等式就能确定每一对变量之间的大小关系。

Input

  • 输入包含多组测试数据。

    每组测试数据,第一行包含两个整数n和m。

    接下来m行,每行包含一个不等式,不等式全部为小于关系。

    当输入一行0 0时,表示输入终止。

Output

  • 每组数据输出一个占一行的结果。

    扫描二维码关注公众号,回复: 7060430 查看本文章

    结果可能为下列三种之一:

    1、”Sorted sequence determined after t relations: yyy…y.”,其中yyy…y是指升序排列的所有变量。
    2、”Sorted sequence cannot be determined.”。
    3、”Inconsistency found after t relations.”。

Data Size

  • 2≤n≤26,变量只可能为大写字母A~Z。

Sample Input

4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0

Sample Output

Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.

题解:

  • Floyd / 拓扑排序。
  • 这题显然是个传递闭包的题,先将i < j写成f(i, j) = 1。然后用Flyod传递下闭包。传完后两层循环枚举i和j,若存在f(i, j)和f(j, i)都为1,说明矛盾。若f(i, j)和f(j, i)都为0,说明不能确定。然后最早确定的位置可以用二分。
  • 嘛但是我试着写了拓扑。
  • 首先i<j的话,连一条i到j的边。显然关系确定的话一定是一条链。那么每加入一组关系,做一次拓扑。如果有环,直接返回矛盾。在拓扑函数内部中,每轮如果队列中出现有>1个点,说明不能确定。最后做完拓扑后,说明是可以确定且无矛盾的,再若涉及到的点已经是全部点,就返回可以。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define N 105
using namespace std;

struct E {int next, to;} e[100005];
int n, m, num;
int h[N], in[N], t[N], seq[N];
bool vis[N], tag[N];
bool rel[N][N];
vector<int> a;

void add(int u, int v)
{
    e[++num].next = h[u];
    e[num].to = v;
    h[u] = num;
}

int topsort()
{
    queue<int> que;
    int flag = 0, cnt = 0;
    for(int i = 1; i <= 26; i++) t[i] = in[i];
    for(int i = 0; i < a.size(); i++)
        if(!in[a[i]]) que.push(a[i]);
    while(que.size())
    {
        if(que.size() > 1) flag = 1;
        int now = que.front(); que.pop();
        seq[++cnt] = now;
        for(int i = h[now]; i != 0; i = e[i].next)
        {
            in[e[i].to]--;
            if(!in[e[i].to]) que.push(e[i].to);
        }
    }
    for(int i = 1; i <= 26; i++) in[i] = t[i];
    if(cnt != a.size()) return -1;
    if(!flag && cnt == n) return 1;
    else return 0;
}

void ini()
{
    a.clear(), num = 0;
    memset(h, 0, sizeof(h));
    memset(vis, 0, sizeof(vis));
    memset(in, 0, sizeof(in));
    memset(rel, 0, sizeof(rel));
}

int main()
{
    while(scanf("%d%d", &n, &m) == 2)
    {
        if(!n && !m) break;
        ini();
        for(int i = 1; i <= m; i++)
        {
            char c[6]; scanf("%s", c);
            int u = c[0] - 'A' + 1, v = c[2] - 'A' + 1;
            if(!rel[u][v])
            {
                rel[u][v] = 1;
                if(!vis[u]) vis[u] = 1, a.push_back(u);
                if(!vis[v]) vis[v] = 1, a.push_back(v);
                add(u, v), in[v]++;
            }
            int ans = topsort();
            if(ans == -1)
            {
                printf("Inconsistency found after %d relations.\n", i);
                for(int j = i + 1; j <= m; j++) scanf("%s", c);
                break;
            }
            else if(!ans && i == m) printf("Sorted sequence cannot be determined.\n");
            else if(ans == 1)
            {
                printf("Sorted sequence determined after %d relations: ", i);
                for(int j = 1; j <= n; j++) printf("%c", (char)(seq[j] - 1 + 'A'));
                printf(".\n");
                for(int j = i + 1; j <= m; j++) scanf("%s", c);
                break;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/BigYellowDog/p/11374702.html