一句话题意:求AOV网的拓扑序列,输出按字典序最小的一个。
拓扑排序 :
由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。
循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。 (摘自 : 百度百科)
方案一,用邻接矩阵来储存图,时间复杂度为 O(n * n),因为代码简单就不贴出来了。
方案二,用优先队列以及前向星来储存时间复杂度为 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; }
时间: 2024-10-10 20:49:24