AcWing 848:有向图的拓扑序列——链式前向星/邻接表+拓扑排序

【题目来源】
https://www.acwing.com/problem/content/850

【问题描述】
给定一个 n 个点 m 条边的有向图,点的编号是 1 到 n,图中可能存在重边和自环。
请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出 −1。
若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A 中都出现在 y 之前,则称 A 是该图的一个拓扑序列。

【输入格式】
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 x 和 y,表示存在一条从点 x 到点 y 的有向边 (x,y)。

【输出格式】
共一行,如果存在拓扑序列,则输出任意一个合法的拓扑序列即可。否则输出 −1。

【输入样例】
5 5
1 3
1 5
2 1
3 4
3 5

【输出样例】
2 1 3 4 5

【数据范围】
1≤n, m≤10^5

【代码】

邻接表+拓扑排序


#include 
using namespace std;
 
const int maxn=1e5+5;
int ind[maxn],path[maxn];
vector g[maxn];
int n,m;

bool topSort() {
    int cnt=0;
    queue q;
 
    for(int i=1; i<=n; i++) {
        if(ind[i]==0) {
            q.push(i);
            path[++cnt]=i;
        }
    }
 
    while(!q.empty()) {
        int t=q.front();
        q.pop();
        for(int i=0; i>n>>m;
    memset(ind, 0, sizeof(ind));
    for(int i=1; i<=m; i++) {
        int x,y;
        cin>>x>>y;
        g[x].push_back(y);
        ind[y]++;
    }
 
    if(topSort()) {
        for(int i=1; i<=n; i++) cout<

链式前向星+拓扑排序

#include 
using namespace std;

const int maxn=1e5+5;
int e[maxn<<1],ne[maxn<<1],h[maxn],idx;
int d[maxn];
int tp[maxn];
int n,m;

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

void top(){
	int hh=0,tt=-1;

	for(int i=1;i<=n;i++){
		if(d[i]==0) tp[++tt]=i;
	}

	while(hh<=tt){
		int t=tp[hh++];
		for(int i=h[t];i!=-1;i=ne[i]){
			int j=e[i];
			d[j]--;
			if(d[j]==0) tp[++tt]=j;
		}
	}

	if(tt==n-1){
		for(int i=0;i>n>>m;
	memset(h,-1,sizeof h);

	while(m--){
		int a,b;
		cin>>a>>b;
		add(a,b);
		d[b]++;
	}
	top();

	return 0;
}

点个赞吧

你可能感兴趣的:(信息学奥赛,拓扑排序+邻接表,链式前向星,算法)