aaa拓扑排序

拓扑排序

今天看书想起来拓扑排序寻思找个板子,然后就有了这篇发泄文章
玛德堡改了三个点。
洛谷P1347

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pi 3.14159265358979323846
typedef pair<ll, ll> PII;

ll t;
ll mp[30][30];
ll in[30] = {0};
char ans[30];
ll topsort(ll n) {
    /*一般情况是一股脑把能排的排序,剩下的再都放到ans。
    如果不能完全排好,一定存在一种情况是队列里的个数>1
    (队列里都是入度为0),所以在中间过程中存在个数>1,不
    一定不能排序,但是如果一直是1,那一定就排好了。
    冲突的情况是如果成环了,那ans里应该少于n,还有自环
    和双向边。
    */
    ll cnt = 0;
    ll tin[n + 10];
    queue<ll> que;
    ll fg = 0;
    for (ll i = 1; i <= n; i++) {
        tin[i] = in[i];

        if (in[i] == 0) {
            que.push(i);
        }
    }

    // cout << que.size() << endl;
    while (!que.empty()) {
        if (que.size() > 1)
            fg = 1;  // 存在无法判断
        ll top = que.front();
        que.pop();
        ans[++cnt] = (char)('A' + top - 1);
        for (ll i = 1; i <= n; i++) {
            if (mp[top][i] == 1 && top != i) {
         
                tin[i]--;
                if (tin[i] == 0) {
                    que.push(i);
                }
            }
        }
    }
    if (cnt != n)
        return -1;
    else if (fg == 1)
        return 0;
    else
        return 1;
}
void solve() {
    ll n, m;
    cin >> n >> m;
    memset(mp, 0, sizeof(mp));
    for (ll i = 1; i <= m; i++) {
        string s;
        cin >> s;
        ll u = s[0] - 'A' + 1;
        ll v = s[2] - 'A' + 1;

        if (!mp[u][v]) {
            mp[u][v] = 1;
            in[v]++;
        } 
      
        if (topsort(n) == -1||u==v||mp[v][u]) {
            printf("Inconsistency found after %lld relations.\n", i);
            return;
        } else if (topsort(n) == 1) {
            printf("Sorted sequence determined after %lld relations: ", i);
            for (ll i = 1; i <= n; i++)
                cout << ans[i];
            cout << '.' << endl;
            return;
        } else {
            continue;
        }
    }
    printf("Sorted sequence cannot be determined.\n");
}
int main() {
    //     ios::sync_with_stdio(0);
    //     cin.tie(0);
    //     cout.tie(0);
    t = 1;
    while (t--) {
        solve();
    }
    return 0;
}
// Sorted sequence determined after 25 relations : ABCDEFGHIJKLMNOPQRSTUVWXYZ.
// Sorted sequence determined after 25 relations : ABCDEFGHIJKLMNOPQRSTUVWXYZ.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值