1. 程式人生 > >拓撲序列以及排序

拓撲序列以及排序

復雜 mil 時間 以及 add emp 前向星 排序 所有

一句話題意:求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;
}

  

拓撲序列以及排序