拓扑排序

给出一些大小关系,然后求出一个总的大小关系。比如:甲>丙, 丙>乙,可以的到一个大小关系:甲 > 丙 > 乙

模板代码:

void toporder(int n) {
    queue<int>q;
    for (int i = 0; i < n; i++) {
        if (!deg[i]) q.push(i);
        // deg[i] 表示第i个点的度数,这里先把度数为0的点加入队列
    }
    while (!q.empty()) {
        int u = q.front(); q.pop();
        // u是排到的点,这里根据情况写
        for (int i = 0; i < (int)G[u].size(); i++) {
            int v = G[u][i];
            if (!--deg[v]) {
                q.push(v);
            }
        }
    }
}

HRBUST 1631 技能修炼

输出拓扑排序的顺序

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define MEM(a) memset(a,0,sizeof(a))
const int N = 510;
int digree[N];
int path[N];
int G[N][N];

int main() {
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF) {
        int u, v;
        MEM(G),MEM(path),MEM(digree);
        for (int i = 1; i <= m; i++) {
            scanf("%d%d", &u, &v);
            G[u][v] = 1;
            digree[v]++;
        }
        priority_queue<int, vector<int>, greater<int> >q;
        for (int i = 1; i <= n; i++) {
            if (!digree[i]) q.push(i);
        }
        int l = 0;
        while (!q.empty()) {
            int cur = q.top();
            path[l++] = cur;
            q.pop();
            for (int i = 1; i <= n; i++) {
                if(G[cur][i]) {
                    digree[i]--;
                    if (!digree[i])
                        q.push(i);
                }
            }
        }
        for (int i = 0; i < l; i++) {
            printf("%d", path[i]);
            if (i != l-1) putchar(' ');
        }
        puts("");
    }
    return 0;
}

HDU 1811 Rank of Tetris

每组测试第一行包含两个整数N,M(0<=N<=10000,0<=M<=20000),分别表示要排名的人数以及得到的关系数。接下来有M行,分别表示这些关系,问能否确定唯一排序关系。

如果一次入队入度为零的点大于1则说明拓扑排序序列不唯一
如果排序的总个数小于给定的个数,则说明存在回路

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int MAXN = 10000 + 5;

int fa[MAXN];
vector<int>G[MAXN];
int deg[MAXN];
int num;
bool cert;

void init(int n) {
    num = n; cert = true;
    for (int i = 0; i <= n; i++) {
        fa[i] = i;
        G[i].clear();
        deg[i] = 0;
    }
}

int findfa(int u) {
    if (fa[u] != u) fa[u] = findfa(fa[u]);
    return fa[u];
}

void unin(int u, int v) {
    int fau = findfa(u);
    int fav = findfa(v);
    if (fau == fav) return;
    if (fau < fav) {
        fa[fav] = fau;
    } else {
        fa[fau] = fav;
    }
    num--;
}

void toporder(int n) {
    queue<int>q;
    for (int i = 0; i < n; i++) {
        if (!deg[i] && fa[i] == i) q.push(i);
    }
    while (!q.empty()) {
        if (q.size() > 1) cert = false;
        int u = q.front(); q.pop();
        num--;
        for (int i = 0; i < (int)G[u].size(); i++) {
            int v = G[u][i];
            if (!--deg[v]) {
                q.push(v);
            }
        }
    }
}


char r[MAXN][10];

int u[MAXN], v[MAXN];

int main() {
    //freopen("in.txt", "r", stdin);
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF) {
        init(n);
        for (int i = 0; i < m; i++) {
            scanf("%d%s%d", &u[i], r[i], &v[i]);
            if (r[i][0] == '=') {
                unin(u[i], v[i]);
            }
        }
        for (int i = 0; i < m; i++) {
            int uu = fa[u[i]], vv = fa[v[i]];
            if (r[i][0] == '<') {
                G[vv].push_back(uu);
                deg[uu]++;
            } else if (r[i][0] == '>') {
                G[uu].push_back(vv);
                deg[vv]++;
            }
        }
        toporder(n);
        if (num > 0) puts("CONFLICT");
        else if (!cert) puts("UNCERTAIN");
        else puts("OK");
    }
    return 0;
}

results matching ""

    No results matching ""