拓扑排序是对有向无环图的一种排序。表示了顶点按边的方向出现的先后顺序。如果有环,则无法表示两个顶点的先后顺序。
在现实生活中,也会有不少应用例子,比如学校课程布置图,要先修完一些基础课,才可以继续修专业课。
一个简单的求拓扑排序的算法:首先要找到任意入度为0的一个顶点,删除它及所有相邻的边,再找入度为0的顶点,以此类推,直到删除所有顶点。顶点的删除顺序即为拓扑排序。
很容易得到拓扑排序的伪代码:
void TopSort(Graph g)
{
for (int i=0; i<vertexnum; i++)
{
vertex v = FindZeroIndegree(g);
if (v is not vertex)
cout <<"the graph has cycle"<<endl;
cout << v ;
foreach vertex w adjacent to v
w.indegree--;
}
}
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#define ll long long
#define LL __int64
const ll INF=9999999999999;
using namespace std;
#define M 400000100
#define inf 0xfffffff
//vector<int,int> G[20002];
//vector<pair<int,int>> ::iterator iter;
//map<ll,int>mp;
//map<ll,int>::iterator p;
int mp[32][32];
int vis[32];
int mark[32];
void clear()
{
memset(mp,0,sizeof(mp));
memset(vis,0,sizeof(vis));
memset(mark,0,sizeof(mark));
}
int topsort(int n)
{
stack<int>s;
int temp[32];
memcpy(temp,vis,sizeof(vis));
bool flag=false;
int u,cnt=0;
for(int i=0;i<n;i++)
if(!temp[i])
s.push(i);//所有入度为0的点入栈,如果这些点多于1的话,序列不确定
while(!s.empty())
{
if(s.size()>1)
flag=true;//序列不确定
u=s.top();
s.pop();
mark[cnt++]=u+'A';//记录出栈的数字
for(int i=0;i<n;i++)
if(mp[u][i])
if(--temp[i]==0)
s.push(i);//入度为0的点入栈
}
if(cnt!=n)//不能拓扑排序,即有环
return 1;
else if(flag)//有多种排序方式,不能唯一确定
return 2;
return 0;//序列能够被唯一确定
}
int main(void)
{
int n,m;
while(scanf("%d %d",&n,&m),n+m)
{
clear();
char s[3];
bool flag1=false,flag2=false;
for(int i=0;i<m;i++)
{
scanf("%s",s);
if(!flag1 && !flag2)
{
if(mp[s[2]-'A'][s[2]-'A']==1)
{
flag1=true;
printf("Inconsistency found after %d relations.\n",i+1);
continue;
}
if(mp[s[0]-'A'][s[2]-'A']==0)
{
mp[s[0]-'A'][s[2]-'A']=1;/*
cout<<mp[s[0]-'A'][s[2]-'A']<<endl;*/
vis[s[2]-'A']++;
}
int ans=topsort(n);
if(ans==0)
{
printf("Sorted sequence determined after %d relations: ",i+1);
for(int j=0;j<n;j++)
printf("%c",mark[j]);
puts(".");
flag2=true;
}
if(ans==1)
{
printf("Inconsistency found after %d relations.\n",i+1);
flag1=true;
}
}
}
if(!flag1 && !flag2)
puts("Sorted sequence cannot be determined.");
}
}