[DOJ练习] 使用邻接表实现AOV网的拓扑排序算法

输入描述

首先输入图中顶点个数和边的条数;
输入顶点的信息(字符型);
输入各顶点的入度;
输入各边及其权值。

输出描述

输出AOV网的拓扑序列(顶点信息),以空格隔开,最后一个顶点后面有空格,如果AOV网存在回路,输出"有回路"的信息,占一行。

输入样例

6 9
A B C D E F
3 0 1 3 0 2
1 0
1 3
2 0
2 3
3 0
3 5
4 2
4 3
4 5

输出样例

B E C D F A 
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 1e5+10;
int n, m;
int h[N], e[N], ne[N], idx;
int q[N];  //队列
int in[N]; //入度
char v[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

bool topSort()
{
    int front = -1, rear = -1;
    
    for(int i = 0; i < n; i ++)
        if(!in[i])
            q[++rear] = i;
            
    while(front != rear)
    {
        int t = q[++front];
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            in[j]--;
            if(!in[j]){
                q[++rear] = j;
            }
        }
    }
    
    return rear == n-1; //q中存的序列实际上就是拓扑序列
}
int main()
{
    cin >> n >> m;
    
    for(int i = 0; i < n; i++) cin>>v[i];
    for(int i = 0; i < n; i++) cin>>in[i];
    
    memset(h, -1, sizeof h);
    int a, b;
    while (m -- )
    {
        scanf("%d%d", &a, &b);
        add(a, b);
    }
    
    if(topSort()){
        for(int i = 0; i < n; i ++) printf("%c ", v[q[i]]);
    }else{
        cout << "有回路";
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Knight02/p/15799040.html