拓扑排序

1、HDU 1285 确定比赛名次

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef pair<int, int> Pair;

const int INF = 0x7fffffff;
const int maxn = 500 + 10;

int N, M;
int head[maxn], Next[2 * maxn], to[2 * maxn], topo[maxn], vis[maxn], in[maxn];
int pos, edge, P1, P2;
bool connect[maxn][maxn];

void init(void);
void add_edge(int u, int v);
void toposort(void);
struct cmp {
    bool operator () (int &a, int &b) { return a > b; }
};

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    while (scanf("%d %d", &N, &M) != EOF) {
        init();
        for (int i = 0; i < M; ++i) {
            scanf("%d %d", &P1, &P2);
            if (!connect[P1][P2]) {
                add_edge(P1, P2); ++in[P2]; connect[P1][P2] = true;
            }
        }
        toposort();
        for (int i = 1; i < N; ++i) { printf("%d ", topo[i]); }
        printf("%d\n", topo[N]);
    }
    return 0;
}

void toposort(void) {
    pos = 0;
    priority_queue<int, vector<int>, cmp> p_q;
    for (int i = 1; i <= N; ++i) {
        if (in[i] == 0) { p_q.push(i); }
    }
    while (!p_q.empty()) {
        int u = p_q.top(); p_q.pop(); topo[++pos] = u;
        for (int i = head[u]; i != -1; i = Next[i]) {
            int v = to[i]; --in[v];
            if (in[v] == 0) { p_q.push(v); }
        }
    }
}

void add_edge(int u, int v) {
    to[edge] = v; Next[edge] = head[u]; head[u] = edge++;
}

void init(void) {
    memset(head, -1, sizeof(head));
    memset(connect, false, sizeof(connect));
    memset(in, 0, sizeof(in));
    edge = 0;
}


2、UVa 10305 Ordering Tasks

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

int G[110][110];
int vis[110];

void toposort(int n);

int main()
{
    int n, m;

    while (cin>>n>>m && !(n==0&&m==0)) {
        memset(G, 0, sizeof(G));
        memset(vis, 0, sizeof(vis));
        int i, j;
        int k;
        for (k=0; k<m; ++k) {
            cin>>i>>j;
            G[i][j] = 1;
            ++vis[j];
        }
        toposort(n);
    }

    return 0;
}

void toposort(int n)
{
    queue<int>Queue1, Queue2;
    int i;
    for (i=1; i<=n; ++i) {
        if (vis[i] == 0) {
            Queue1.push(i);
        }
    }
    while (!Queue1.empty()) {
        int f = Queue1.front();
        Queue1.pop();
        Queue2.push(f);
        for (i=1; i<=n; ++i) {
            if (G[f][i] > 0) {
                --vis[i];
                if (vis[i] == 0) {
                    Queue1.push(i);
                }
            }
        }
    }
    if (!Queue2.empty()) {
        cout<<Queue2.front();
        Queue2.pop();
    }
    while (!Queue2.empty()) {
        cout<<" "<<Queue2.front();
        Queue2.pop();
    }
    cout<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值