码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序模板

时间:2015-09-06 12:40:50      阅读:296      评论:0      收藏:0      [点我收藏+]

标签:

拓扑排序是图论中,按照有向边的进入顺序依次排序,在有环的图中不存在拓扑排序。

首先是小白书上的拓扑排序模板,用的是DFS建立拓扑排序,但是似乎除了一般的拓扑排序以外什么都做不了……求字典序最小或者输出全部答案都不适用……

 

 1 int vis[maxm],topo[maxm],t;
 2 
 3 bool dfs(int s){
 4     vis[s]=-1;
 5     for(int i=head[s];~i;i=nxt[i]){
 6         int j=point[i];
 7         if(vis[j]==-1)return 0;
 8         if(!vis[j]&&!dfs(j))return 0;
 9     }
10     vis[s]=1;
11     topo[t--]=s;
12     return 1;
13 }
14 
15 bool toposort(int n){
16     t=n;
17     memset(vis,0,sizeof(vis));
18     for(int i=1;i<=n;++i){
19         if(!vis[i]){
20             if(!dfs(i))return 0;
21         }
22     }
23     return 1;
24 }

 

 

接下来是BFS实现的,一般用队列就可以满足需要了,如果要求字典序最小,可以改成优先队列实现,但是只能输出一个排序。在过程中可以加入判断,每次从队列中取出元素删除后,判断队列是否为空,若任意一次不为空则可以说明拓扑序不唯一。

 

 1 int ans,n;
 2 int id[maxn],num[maxn];
 3 int head[maxn],point[maxm],nxt[maxm],size;
 4 
 5 void add(int a,int b){
 6     point[size]=b;
 7     nxt[size]=head[a];
 8     head[a]=size++;
 9     id[b]++;
10 }
11 
12 bool topo(){
13    //  priority_queue<int,vector<int>,greater<int> >q;
14     queue<int>q;
15     for(int i=1;i<=n;++i)if(!id[i])q.push(i);
16     int cnt=0;
17     while(!q.empty()){
18         int u=q.front();q.pop();
19         cnt++;
20         for(int i=head[u];~i;i=nxt[i]){
21             int j=point[i];
22             id[j]--;
23             if(!id[j])q.push(j);
24         }
25     }
26     if(cnt==n)return 1;
27     return 0;
28 }

 

 

 

 

然后是DFS版,可以实现输出所有拓扑序的输出,并且通过进入DFS的顺序的控制也基本能实现字典序输出。

 1 int ma[maxm][maxm],id[maxm],n,vis[maxm],v[maxm];
 2 int ans[maxm];
 3 
 4 void dfs(int s,int t){
 5     ans[t]=s;
 6     v[s]=1;
 7     if(t==n){
 8         for(int i=1;i<=n;++i){
 9                         printf("%d",ans[i]);
10                 if(i==n)printf("\n");
11                         else printf(" ");
12                 }
13         v[s]=0;
14         return;
15     }
16     int que[maxm],cnt=0;
17     for(int i=1;i<=n;++i){
18         if(ma[s][i])id[i]--;
19         if(vis[i]&&!id[i]&&!v[i])que[++cnt]=i;
20     }
21     for(int i=1;i<=cnt;++i)dfs(que[i],t+1);
22     for(int i=1;i<=n;++i)if(ma[s][i])id[i]++;
23     v[s]=0;
24 }
25 
26 for(int i=1;i<=n;++i){
27     if(vis[i]&&!id[i])dfs(i,1);
28 }

 

拓扑排序模板

标签:

原文地址:http://www.cnblogs.com/cenariusxz/p/4785058.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!