拓扑排序 洛谷P1347 排序

题目链接

LG P1347

题解

题意

找出拓扑排序。
注意题目给的三种特殊情况。

思路

题目给出的是小于关系,可以看作边。
看一下题目给的范围并不是特别大,可以来一个边judge一次。

  1. 碰到环则立即输出;
  2. 判断已输入的节点数量与总节点数量是否相等,不相等则继续判断,相等则输出已确定。

注意一下重复边,可以直接跳过,否则注意不要重复记录入度。
注意一下输出格式,不要漏了某个点QAQ

AC代码

#include <bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;
int const N = 30;
int e[N][N];
int in[N], tmp[N];
int n, m;
char ch[4];
set<int> st;
bool vis[N];
vector<int> ans;

int topological() {
    
    
    queue<int> q;
    int cnt = 0;
    ans.clear();
    copy(begin(in), end(in), begin(tmp));
    for (int i = 1; i <= n; i++) {
    
    
        if (tmp[i] == 0 && st.find(i) != st.end()) {
    
    
            q.push(i);
            vis[i] = true;
        }
    }
    mms(vis, false);
    bool flag = true;

    while (!q.empty()) {
    
    
        int x = q.front();
        q.pop();

        cnt += 1;
        ans.push_back(x);

        int num = 0;
        for (int y = 1; y <= 26; y++) {
    
    
            if (e[x][y] == 1) {
    
    
                tmp[y] -= 1;
                if (tmp[y] == 0 && !vis[y]) {
    
    
                    num += 1;
                    if (num > 1) flag = false;
                    q.push(y);
                    vis[y] = true;
                }
            }
        }
    }

    if (cnt < st.size()) return -1;
    else if (cnt == n && flag) return 1;
    return 0; // 没有必要,至少不写有点不舒服QAQ
}

int main() {
    
    
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
    
    
        scanf("%s", ch);
        int x = ch[0] - 'A' + 1;
        int y = ch[2] - 'A' + 1;
        st.insert(x);
        st.insert(y);
        if (e[x][y] == 1) continue;
        e[x][y] = 1;
        in[y] += 1;
        int ret = topological();
        if (ret == -1) {
    
    
            printf("Inconsistency found after %d relations.", i);
            return 0;
        } else if (ret == 1) {
    
    
            printf("Sorted sequence determined after %d relations: ", i);
            for (auto item : ans) printf("%c", 'A' + item - 1);
            printf(".");
            return 0;
        }
    }
    printf("Sorted sequence cannot be determined.");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45934120/article/details/108678790