拓扑序列以及排序

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

  

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拓扑排序是一个用来识别有向图中节点的线性排序的算法。在C语言中,我们可以通过深度优先搜索(DFS)和拓扑排序的方法来输出所有可能的拓扑排序序列。 首先,我们需要定义一个有向图,并且用邻接矩阵或邻接表的形式存储这个图。然后,我们可以利用深度优先搜索来遍历这个图,并且按照拓扑排序的要求将节点进行排序。 在C语言中,我们可以定义一个函数来进行深度优先搜索,根据访问节点的顺序来输出所有可能的拓扑排序序列。具体的实现可以参考下面的伪代码: ```c // 定义一个有向图的邻接表结构 typedef struct { int numVertices; int** adjMatrix; } Graph; // 定义一个函数来进行深度优先搜索 void dfs(Graph* graph, int* visited, int vertex, int* stack, int* top) { visited[vertex] = 1; for (int i = 0; i < graph->numVertices; i++) { if (graph->adjMatrix[vertex][i] && !visited[i]) { dfs(graph, visited, i, stack, top); } } stack[++(*top)] = vertex; } // 定义一个函数来输出所有可能的拓扑排序序列 void printAllTopologicalSorts(Graph* graph) { int* visited = (int*)malloc(graph->numVertices * sizeof(int)); int* stack = (int*)malloc(graph->numVertices * sizeof(int)); int top = -1; for (int i = 0; i < graph->numVertices; i++) { visited[i] = 0; } for (int i = 0; i < graph->numVertices; i++) { if (!visited[i]) { dfs(graph, visited, i, stack, &top); } } while (top != -1) { printf("%d ", stack[top--]); } free(visited); free(stack); } ``` 通过上面的伪代码,我们可以实现在C语言中输出所有可能的拓扑排序序列的功能。只需要将定义图的邻接表结构和调用打印函数,并将实际的有向图传入即可得到结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值