拓扑排序模板加例题(拓扑排序问题汇总)

版权声明:欢迎转载,请注明出处٩(๑❛ᴗ❛๑)۶ https://blog.csdn.net/love_phoebe/article/details/81660640

概念:一个有向无环图的拓扑序列是将图中的顶点排成一个线性序列,使得对于图中任意一对顶点u,v。若存在边<u,v>,则线性序列中u出现在v之前。

算法实现:

(1)若图中的点入度均大于0则不存在拓扑序列,否则进行第二步

(2)取一个入度为0的点u并将其放置序列末尾

(3)删除点u以及从u伸出的边,即将与u相连的点的入度减1

(4)若图中还存在顶点,再从(1)开始

模板:

#include<cstdio> 
#include<vector>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
const int maxn=1e3;
vector<int>grid[maxn];
int indu[maxn];
void find(int n){
	queue<int>Q;
	for(int i=1;i<=n;i++)if(indu[i]==0)Q.push(i),cout<<i<<",";
	while(!Q.empty()){
		int now=Q.front();Q.pop();
		for(int i=0;i<grid[now].size();i++){
			int next=grid[now][i];
			if(--indu[next]==0)Q.push(next),cout<<next<<",";
		}
	}
	cout<<endl;
}
int main(){
	int n,m;
	while(~scanf("%d%d",&n,&m)){
		for(int i=1;i<=n;i++)grid[i].clear();
		memset(indu,0,sizeof(indu));
		for(int i=0;i<m;i++){
			int p1,p2;
			scanf("%d%d",&p1,&p2);
			grid[p1].push_back(p2);//p1到p2有一条边
			indu[p2]++;
		}
		find(n);
	}
	return 0;
}

 

题目:

基本应用之有向图判环:在while循环中加入计数,当循环结束时如果循环次数等于顶点个数,则证明n个顶点入度都已经为0 ,存在拓扑序列,则图中不存在环,反之有环,题目:HUD-3342

学会反向建图及按题意确定输出次序:HUD-1285

#include<iostream> 
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#define MM(a) memset(a,0,sizeof(a));
using namespace std;
const int maxn=510;
vector<int>grid[maxn];
int indu[maxn];
void find(int N){
	priority_queue<int,vector<int>,greater<int> >Q;
	for(int i=1;i<=N;i++)if(indu[i]==0)Q.push(i);
	vector<int>ans;
	while(!Q.empty()){
		int now=Q.top();Q.pop();
		//printf("-%d-\n",now);
		ans.push_back(now);
		for(int i=0;i<grid[now].size();i++){
			int next=grid[now][i];
			if(--indu[next]==0)Q.push(next);
		}
	}
	for(int i=0;i<ans.size();i++){
		printf("%d",ans[i]);
		if(i==ans.size()-1)printf("\n");
		else printf(" ");
	}
}
int main(){
	int N,M;
	while(scanf("%d%d",&N,&M)==2 &&N){
		for(int i=1;i<=N;i++)grid[i].clear();
		MM(indu);
		for(int i=0;i<M;i++){
			int p1,p2;
			scanf("%d%d",&p1,&p2);
			grid[p1].push_back(p2);//p2输给p1
			indu[p2]++;
		}
		find(N);
	}
	return 0;
}

福利题:poj-3687 Labeling Balls(别问我福利是啥,做了就知道了,嘿嘿)

 

 

 

展开阅读全文

没有更多推荐了,返回首页