# [算法导论读书笔记]拓扑排序

2132人阅读 评论(0)

算法导论中关于拓扑排序部分，讲得真是太好了。比按节点的入度的贪心法的拓扑排序容易理解，且容易实现。实现方法是这样的，用DFS遍历整个图，得出个节点的完成时间，然后按完成时间倒序排列就得到了图的拓扑排序序列。

#include <iostream>
#include <stdio.h>
#include <string.h>

#include <list>
using namespace std;

class Graph
{
private:
int v;
int times;//时间戳
int *f;//记录节点的完成时刻
int *tp;// 按finish的时间倒序存放在tp序列中
void DFSUtil(int v, bool visited[]);
public:
Graph(int v);//Construtor
~Graph();//Construtor
void DFS( /*int v*/);//DFS traversal of the vertices reachable from v
void TopolgicalSort();
};

Graph::Graph(int v)
{
this->v = v;
this->times = 0;
f = new int[v];
tp = new int[v];
memset(f, 0, sizeof(f[0])*v);
memset(tp, 0, sizeof(tp[0])*v);
}

{
}

void Graph::DFSUtil(int v, bool visited[])
{
//Mark the current node as node visited and print it
if( visited[v] == false)
{
visited[v] = true;
printf("%c  ", 'A' + v);

//Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
{
if( !visited[*i])
{
DFSUtil(*i, visited);
}
}
f[v] = ++times;
}
}

void Graph::DFS(/*int v*/)
{
//Mark all the vertices as not visited
bool *visited = new bool[v];
for( int i = 0; i < v; i++)
visited[i] = false;
//Call the recrusive helper function to print DFS tracersal
for( int i = 0; i < v; i++)
DFSUtil(i, visited);
printf("\n");
}

void Graph::TopolgicalSort()
{
for( int i = 0; i < v; i++)
{
tp[v - f[i]] = i;// f的取值为 1——v,正好，tp[ v - fp[i]] 是节点的正确位置
}

for( int j = 0; j < v; j++)
{
printf("%c  ", tp[j] + 'A');
}
printf("\n");
}

Graph::~Graph()
{
delete [] f;
delete [] tp;
}

int main(int argc, char* argv[])
{
// 0:A 1:B 2:C 3:D 4:E 5:F 6:G 7:H 8:I
Graph g(9);

g.DFS();
g.TopolgicalSort();

return 0;
}


http://blog.sina.com.cn/s/blog_6ec5c2d00100szit.html

poj 1094 Sorting It All Out

// poj 1094 TopSort
#include<iostream>
using namespace std;
#define MAXN 29

int N,M;
int cnt[MAXN];
char order[MAXN];
void joy_init()
{
}
int joy_topsort()
{
memset(cnt,0,sizeof(cnt));
memset(order,'\0',sizeof(order));
int i,j,k;
bool flag=true;
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
}
}
for(i=1;i<=N;i++)cout<<cnt[j]<<" ";cout<<endl;
for(k=1;k<=N;k++)
{
i=0;
for(j=1;j<=N;j++)
{
if(cnt[j]==0)
{
if(i==0) i=j;
else flag=false;
//找出入度为0的点
}
}

if(i==0) return 0;
// 0 是矛盾（表示成环了）；1，是确定；2是不确定；
cnt[i]=-1;
order[k-1]=i+'A'-1;
for(j=1;j<=N;j++)
{
}
}
if(flag) return 1;
else return 2;
}
int main()
{
int i,j,a,b,result;
char s[10];
while(scanf("%d%d",&N,&M))
{
if(N==0&&M==0) break;
joy_init();
bool h=false
for(i=1;i<=M;i++)
{
scanf("%s",s);
if(h) continue;
a=s[0]-'A'+1;b=s[2]-'A'+1;
result=joy_topsort();
if(result==0)
{
printf("Inconsistency found after %d relations.\n",i);
h=true;
}
else if(result==1)
{
printf("Sorted sequence determined after %d relations: %s.\n",i,order);
h=true;
}
}
if(!h) printf("Sorted sequence cannot be determined.\n");
}
system("pause");
return 0;
}

poj 2367 Genealogical tree

poj 3272 Cow Traffic

poj 3687 Labeling Balls

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：710932次
• 积分：7772
• 等级：
• 排名：第2696名
• 原创：135篇
• 转载：35篇
• 译文：7篇
• 评论：119条
声明
本博客乃学习笔记，没有纯粹无意义的转载。作者除了对自己负责，不对任何读者负责。欢迎指出文章错误，如果原意交朋友，可以通过Gmail联系我（mingxinglai#gmail.com），博客基本不再更新，欢迎访问我的独立博客http://mingxinglai.com
文章分类
评论排行
最新评论