Uva--10305 Ordering Tasks(拓扑排序)

记录
15:42 2023-5-26

reference:《算法竞赛入门经典第二版》例题6-15
拓扑排序
一种是书上利用dfs
还有一种是我之前学过的利用bfs的,每次找入度为0的节点入栈,出栈的时候,把其它节点的入度减一,减到0的节点就再入栈

使用dfs

#include<cstdio>
#include<cstring>
#define MAX_N 1000
using namespace std;
typedef long long ll;
typedef unsigned int uint;
const int INF = 0x3f3f3f3f;

int G[MAX_N][MAX_N];
int visited[MAX_N]; // 0表示未访问 1表示访问过 -1表示正在访问
int tops[MAX_N];
int t;
int N, M;

bool dfs(int u) {
    visited[u] = -1;
    for(int i = 1; i <= N; i++) {
        if(G[u][i]) {
            //i访问到正在访问的节点 表示有回环
            if(visited[i] == -1) return false;
            else if(!visited[i] && !dfs(i)) return false;
        }
    }
    visited[u] = 1;
    tops[t--] = u;
    return true;
}

bool solve() {
    t = N;
    memset(visited, 0, sizeof(visited));
    for(int i = 1; i <= N; i++) {
        if(!visited[i]){
            if(!dfs(i)) return false;
        }
    }
    return true;
}

int main () {
    while (scanf("%d%d", &N, &M) == 2 && N) {
        memset(G, 0, sizeof(G));
        int s, e;
        for(int i = 0; i < M; i++) {
            scanf("%d%d", &s, &e);
            G[s][e] = 1;
        }
        if(solve()) {
            for(int i = 1; i < N; i++) {
                printf("%d ", tops[i]);
            }
            printf("%d\n", tops[N]);
        } else {
            printf("No\n");
        }
    }
}

使用bfs

#include<cstdio>
#include<cstring>
#include<queue>
#define MAX_N 1000
using namespace std;
typedef long long ll;
typedef unsigned int uint;
const int INF = 0x3f3f3f3f;

int G[MAX_N][MAX_N];
int indegree[MAX_N];
int tops[MAX_N];
int t = 1;
int count = 0;
int N, M;
queue<int> q;

bool topsort() {
    for(int i = 1; i <= N; i++) {
        if(indegree[i] == 0) {
            q.push(i);
            count++;
        }
    }
    while (!q.empty()) {
        int u = q.front();q.pop();
        tops[t++] = u;
        for(int i = 1; i <= N; i++) {
            if(G[u][i]) {
                if(--indegree[i] == 0) {
                    q.push(i);
                    count++;
                }
            }
        }
    }
    if(count != N) return false;
    return true;
}

int main () {
    while (scanf("%d%d", &N, &M) == 2 && N) {
        memset(G, 0, sizeof(G));
        memset(indegree, 0, sizeof(indegree));
        count = 0;
        t = 1;
        int s, e;
        for(int i = 0; i < M; i++) {
            scanf("%d%d", &s, &e);
            G[s][e] = 1;
            indegree[e]++;
        }
        if(topsort()) {
            for(int i = 1; i < N; i++) {
                printf("%d ", tops[i]);
            }
            printf("%d\n", tops[N]);
        } else {
            printf("No\n");
        }
    }
}
posted @ 2023-05-26 15:51  57one  阅读(6)  评论(0编辑  收藏  举报