【专题】拓扑排序 入门版
来源:互联网 发布:网络电视怎样看中央台 编辑:程序博客网 时间:2024/06/01 15:47
(注:如果你是提高组+的大牛,敬可忽略本文 谢谢合作)
拓扑排序(标题一定要大大大~~~)
耙耙说,要先把概念搬出来:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
(这么不要脸的从百度百科搬来真的好吗。。。)、
好吧,其实你只要知道,什么是有向无环图,就够了。。。(逗我呢)
先搬出来一道例题:
题2历史事件
【问题描述】
一些历史迷们打算把历史上的一些大事件按时间顺序列出来。但是,由于资料不全,每个事件发生的具体时间都没有找到。幸运的是,他们记得一些事件之间的先后关系。他们把事件分别编号1,2,3,……n,然后把一些先后关系列出。不过,这些复杂的先后关系仍然把他们难倒了。你能够帮助他们吗?
【输入文件】
输入文件event.in。第一行是两个整数n,m(1<=n<=1000,1<=m<=100000),分别表示事件数和已知的先后关系数。接下来m行,第i行是两个整数xi,yi(1<=xi,yi<=n),表示事件xi比事件yi先发生。
【输出文件】
输出文件event.out。按事件发生的时间顺序列出事件的编号,每行一个,若存在多种可能,输出第一个事件编号最小的,若第一个事件编号相同,则输出第二个事件编号最小的……;若没有满足条件的编号序列,输出一行’Error!’)。
【样例输入】
3 2
1 2
1 3
【样例输出】
1
2
3
这题真的是纯拓扑纯拓扑纯拓扑(重要的事情说三遍)
实际上,题目的意思就是拓扑的作用、原理吧。。。
以上图为例(请勿吐槽)先说明一些东西:
入度:即有多少条边指向某个顶点(有向图) 例如上图中顶点2的入度为2
出度:即某个顶点向外指向的边有多少条 例如上图中顶点2的出度为1
每一次,选一个入度为 0 的顶点输出(如上图顶点1),然后将其所有后继顶点的入度-1(即把这个顶点往外伸展的边删除),重复这两步直至输出所有顶点,或找不到入度为 0 的顶点为止(这就是有“环”的情况)
上面的例子排序后的序列为0 1 2 4 3 5 7 8 (自己演算去)
找到一个入度为0的点并处理完后,再重新从1到n找(越小越好)
<span style="font-size:14px;color:#330033;">var n,m,i,x,y,t,j,k:longint; rd,cd,b,c:array[1..1001] of longint; f:array[1..1001,1..1001] of longint; p:boolean;{procedure tuopu;var i,j:longint; p:boolean;begin p:=false; for i:=1 to n do begin if rd[i]=0 then begin p:=true; rd[i]:=-1; for j:=1 to n do begin if (f[i,j]=1)and(i<>j) then begin f[i,j]:=0; dec(rd[j]); end; end; inc(t); c[t]:=i; end; end; if not p then begin writeln('Error!'); halt; end;end;} (请忽略此段,错误打法)procedure ex;begin writeln('Error!'); close(input); close(output); halt;end;begin assign(input,'event.in');reset(input); assign(output,'event.out');rewrite(output); readln(n,m); for i:=1 to m do begin readln(x,y); if f[x,y]=1 then continue; f[x,y]:=1; inc(rd[y]); end; i:=0; while i<n do begin p:=false; j:=1; for k:=1 to n do if rd[k]=0 then begin (判断是否有环) p:=true; break; end; if not p then ex; while rd[j]<>0 do inc(j);(找入度为0的点) rd[j]:=-1; for k:=1 to n do if f[j,k]=1 then begin dec(rd[k]); f[j,k]:=0; end;(处理) inc(i); c[i]:=j; end; for i:=1 to n do writeln(c[i]); close(input); close(output);end.</span><span style="color:#003366;font-size:18px;"></span>还有,数据好坑,输入还有重复的情况。。。。。(逗我吗)
- 【专题】拓扑排序 入门版
- 拓扑排序专题
- 拓扑排序专题
- 拓扑排序专题
- 拓扑排序专题
- POJ2367 拓扑排序入门
- POJ2367拓扑排序入门
- poj2367 拓扑排序入门
- 拓扑排序入门
- 拓扑排序入门
- 拓扑排序入门
- 图论专题小结:拓扑排序
- 拓扑排序入门题1
- hdu 1285 拓扑排序 入门
- HDU 1285 拓扑排序入门
- 【个人专题一】强连通+拓扑排序——Poj_2762
- hdu 1285 拓扑排序入门题
- POJ 2367 Genealogical tree 拓扑排序入门
- iOS 核心动画 书籍
- explain中的key_len
- Android总结02_Touch事件的分发与消费机制
- ArcGIS教程:什么是 Python?
- LTE中QPSK、16QAM、64QAM什么意思?有什么区别,分别在什么情况下占用呢?
- 【专题】拓扑排序 入门版
- poj 2115 C Looooops (扩展欧几里得算法)
- static和extern 的区别
- 关于TOMCAT配置问题
- 关于使用百度地图API 检验码230报错问题
- 查看软件是32位还是64位
- oracle数据库 编译无效存储过程
- GPUImage写双输入的滤镜
- webSphere缓存问题