拓扑序列以及排序

一句话题意:求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

拓扑序列以及排序的相关文章

图结构练习——推断给定图是否存在合法拓扑序列(拓扑排序推断环)

图结构练习--推断给定图是否存在合法拓扑序列 Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 给定一个有向图,推断该有向图是否存在一个合法的拓扑序列. 输入 输入包括多组.每组格式例如以下. 第一行包括两个整数n,m.分别代表该有向图的顶点数和边数.(n<=10) 后面m行每行两个整数a b.表示从a到b有一条有向边. 输出 若给定有向图存在合法拓扑序列,则输出YES.否则输出NO. 演示样例输入 1 0 2 2 1 2 2 1 演示样例输出 YES

图结构练习——判断给定图是否存在合法拓扑序列

图结构练习——判断给定图是否存在合法拓扑序列 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个有向图,判断该有向图是否存在一个合法的拓扑序列. 输入 输入包含多组,每组格式如下. 第一行包含两个整数n,m,分别代表该有向图的顶点数和边数.(n<=10) 后面m行每行两个整数a b,表示从a到b有一条有向边. 输出 若给定有向图存在合法拓扑序列,则输出YES:否则输出NO. 示例输入 1 0 2 2 1 2 2 1 示例输出 YES NO #inc

拓扑序列 之 hdu 5154 Harry and Magical Computer

/* AOV网(Activity On Vertex Network): 用图来表示工程:其中,用顶点表示活动:弧表示活动之间的制约关系. 工程是否顺利进行?---->AOV网是否存在有向回路 ******************************************* 用产生(包含所有) 顶点序列的方法,顶点序列满足: 在图中,若顶点vi到顶点vj存在路径, 则在序列中,顶点vi领先于顶点vj. 满足上述条件的顶点序列称为拓扑序列, 产生这一序列的过程称为拓扑排序. ********

拓扑序列变形 之 poj 1094 Sorting It All Out

/* 拓扑序列变形 之 poj 1094 Sorting It All Out 变形: 在每消去唯一一个入度为0的点后,只剩下唯一一个入度为0的点. 这样获得的n个点才是排序好的. */ 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstddef> 5 #include <iterator> 6 #include <algorithm&

数据结构实践项目——最短路径和拓扑序列

本文是针对[数据结构基础系列(7):图]的第2组实践例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) 0710 生成树的概念 0711 最小生成树的普里姆算法 0712 最小生成树的克鲁斯卡尔算法 0713 从一个顶点到其余各顶点的最短路径 0714 每对顶点之间的最短路径 0715 拓扑排序 0716 AOE网与关键路径 纸上谈兵:"知原理"检验题目 1.针对下面的图1: (图1) (1)写出图的邻接矩阵: (2)按照Prim算

(hdu step 5.2.5)确定比赛名次(求拓扑序列)

题目: 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 337 Accepted Submission(s): 180   Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得

拓扑序列的最小字典序列

查错 考场上又写挂的一道签到题... 我们发现这题要求得到一个最小字典序列 显然找到所有序列然后排序是不可取的, 那么我们不能使用平常的拓扑排序方法,怎么搞使得在每次处理拓扑顺序的时候来维护呢? 用小根堆维护入度为0的点即可,输入的时候统计入度 {$inline on} const maxn=100010; type node=record pos,next:longint; end; var heap,getin,head,ans:array[0..maxn] of longint; edge

Southern African 2001 框架折叠 (拓扑序列的应用)

题目:考虑五个图片堆叠在一起,比如下面的9 * 8 的矩阵表示的是这些图片的边缘框. 现在上面的图片顺序为图片1放在最底下,5放在最顶上.如果任何图片的边框覆盖了其他图片的边框,被覆盖的部分不会被显示出来. 下面是一个栗子: 那么从低向上图片的堆叠顺序为 EDABC,现在的问题是给出一个堆叠后的表示,要确定从低向上的图片的堆叠顺序. 下面是判定规则: 1.图片一定是由一个字母表示并且每条边至少三个字符 2.题目保证至少会给出每条边的一个字母,一个角的一个字符代表两条边 3.图片边框用大写字母表示

求有向无环图的所有拓扑序列

腰酸背痛一个上午,终于搞定了.. 一 用到二个工具: 1.回溯法的算法思想 2.顺序表(主要用到了删除操作) 二 程序设计步骤: 1.读入图: 这里我没有用严格的图结构.而是用邻接矩阵来表示图,邻接矩阵放在一个txt文件中.(见后文) 读入图就是指读入这个文件. 2.计算图中顶点的入度: 用一个结构体数组来存放顶点名称和顶点的入度(我这里的结构体名称是ElemType) 3.初始化顺序表 这一步只需初始化第0号顺序表... 用2中的顶点入度数组来初试化. 4.开始计算拓扑序列 这里我们把图的每个