一句话题意:求AOV网的拓扑序列,输出按字典序最小的一个。
拓扑排序 :
由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。
循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。 (摘自 : 百度百科)
方案一,用邻接矩阵来储存图,时间复杂度为 O(n * n),因为代码简单就不贴出来了。
想了想又贴出来了
#include<bits/stdc++.h>
#define maxn 1000
using namespace std;
int book[maxn][maxn],du[maxn];
int n,m,x,y;
void topusort()
{
int num=n;
while(num--)
{
int k;
for(int i=1;i<=n;i++)
if(du[i]==0)
{
cout<<i<<" ";
k=i;
du[i]=-1;
break;
}
for(int j=1;j<=n;j++)
if(book[k][j]==1)
{
book[k][j]=0;
du[j]--;
}
}
}
int main()
{
cin>>n>>m;
while(m--)
{
cin>>x>>y;
book[x][y]=1;
du[y]++;
}
topusort();
return 0;
}
方便你们理解~
方案二,用优先队列以及前向星来储存时间复杂度为 O(n+e)
证明过程:n顶点e条弧向图言建立求各顶点入度间复杂度O(e);建零入度顶点栈间复杂度O(n);拓扑排序程若向图环则每顶点进栈、栈入度减1操作while语句总共执行e所总间复杂度O(n+e)
我在代码中还加了运算符重载,struct cmp函数其实等同于greater,不会用也没有关系
#include<bits/stdc++.h>
using namespace std;
struct Edge
{
int to,next,w;
};
struct Edge edge[20000];
int book[2000];
int n,m;
int head[2000];
int cnt=0;
void add(int x,int y)
{
book[y]++;//表示入度
edge[++cnt].to=y;
edge[cnt].next =head[x];
head[x]=cnt;
}
struct cmp
{
bool operator () (const int a,const int b )const
{
return a>b;
}
};
void toposort(int n)
{
priority_queue <int ,vector <int>, cmp> que;
for(int i=1;i<=n;i++)
if(book[i]==0)
{
book[i]--;
que.push(i);
}
int k=1;
while(!que.empty())
{
int u=que.top();que.pop();
char str;
str=((k++!=n)?' ':'\n');//逗比到不行的判断是否在文末的方法
cout<<u<<str;
for(int i=head[u];i;i=edge[i].next)
{
int j=edge[i].to;
book[j]--;
if(book[j]==0)
que.push(j);
}
}
}
int main()
{
int x,y;
cin>>n>>m;
while(m--)
{
cin>>x>>y;
int ok=0;
for(int i=head[x];i;i=edge[i].next)
if(edge[i].to==y)
{ok=1;break; } //判断重边
if(!ok)
add(x,y);
}
toposort(n);//n个点
return 0;
}