标签:style blog io ar os sp for on div
John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed.
0 0
(The Joint Effort Contest, Problem setter: Rodrigo Malta Schmidt)
题目大意:有n个变量,和m个二元组关系。关系(x,y)表示x<y。现在讲所有变量
从小到大来排序,进行输出。
例如:有4个变量a、b、c、d,若a<b,c<b,d<c,则排序后的可能为a<d<c<b,
也有其他可能d<a<c<d。只要输入其中一个就可。
思路:把n个变量看成是n个点,“x<y”看做是一条边,则得到一个有向图。对图的
节点进行排序,使得每一条有向边(x,y)对应的x都在y前边。即所谓的拓扑排序。
DFS进行拓扑排序,如果存在有向环,则不存在拓扑排序,否则就将访问完的结点
假如到当前拓扑序列的前边。具体过程参考代码。
参考:算法竞赛入门经典(第二版)P168~169
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int vis[1100]; int topo[1100],G[1100][1100],t,n,m; bool dfs(int u) { vis[u] = -1;//开始访问结点 for(int v = 0; v < n; v++) { if(G[u][v])//存在边 { if(vis[v]<0)//表示结点v正在访问中,(即调用dfs(u)还在栈中,尚未返回) return false; else if(!vis[v])//没有访问过该结点 dfs(v);//访问该结点 } } vis[u] = 1;//结点访问结点 topo[--t] = u;//存储当前结点到拓扑序的首部 return true; } bool toposort() { t = n; memset(vis,0,sizeof(vis)); for(int u = 0; u < n; u++) { if(!vis[u]) if(!dfs(u)) return false; } return true; } int main() { while(~scanf("%d%d",&n, &m) && (n||m)) { memset(G,0,sizeof(G)); while(m--) { int u,v; scanf("%d%d",&u,&v); G[--u][--v] = 1; } if(toposort()) { for(int i = 0; i < n; i++) { if(i!=n-1) printf("%d ",topo[i]+1); else printf("%d\n",topo[i]+1); } } else printf("No\n"); } return 0; }
UVA10305 Ordering Tasks【DFS】【拓扑排序】
标签:style blog io ar os sp for on div
原文地址:http://blog.csdn.net/lianai911/article/details/41898141