图结构练习——判断给定图是否存在合法拓扑序列
2015-08-11 08:37
288 查看
一、概述
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。
通常,这样的线性序列称为满足拓扑次序(TopoiSicai Order)的序列,简称拓扑序列。
二、无前趋的顶点优先的拓扑排序方法
该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:
NonPreFirstTopSort(G){//优先输出无前趋的顶点
while(G中有人度为0的顶点)do{
从G中选择一个人度为0的顶点v且输出之;
从G中删去v及其所有出边;
}
if(输出的顶点数目<|V(G)|)
//若此条件不成立,则表示所有顶点均已输出,排序成功。
Error("G中存在有向环,排序失败!");
}
三、无后继的顶点优先的拓扑排序方法
1、思想方法
该方法的每一步均是输出当前无后继(即出度为0)的顶点。对于一个DAG,按此方法输出的序列是逆拓扑次序。因此设置一个栈(或向量)T来保存输出的顶点序列,即可得到拓扑序列。若T是栈,则每当输出顶点时,只需做人栈操作,排序完成时将栈中顶点依次出栈即可得拓扑序列。若T是向量,则将输出的顶点从T[n-1]开始依次从后往前存放,即可保证T中存储的顶点是拓扑序列。
2、抽象算法描述
算法的抽象描述为:
NonSuccFirstTopSort(G){//优先输出无后继的顶点
while(G中有出度为0的顶点)do {
从G中选一出度为0的顶点v且输出v;
从G中删去v及v的所有人边 }
if(输出的顶点数目<|V(G)|)
Error("G中存在有向环,排序失败!"); }
图结构练习——判断给定图是否存在合法拓扑序列Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^题目描述给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。输入输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)后面m行每行两个整数a b,表示从a到b有一条有向边。输出若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。示例输入1 02 21 22 1示例输出YESNO
1、无前趋的顶点优先的拓扑排序
2、无后缀的顶点优先拓扑排序
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。
通常,这样的线性序列称为满足拓扑次序(TopoiSicai Order)的序列,简称拓扑序列。
二、无前趋的顶点优先的拓扑排序方法
该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:
NonPreFirstTopSort(G){//优先输出无前趋的顶点
while(G中有人度为0的顶点)do{
从G中选择一个人度为0的顶点v且输出之;
从G中删去v及其所有出边;
}
if(输出的顶点数目<|V(G)|)
//若此条件不成立,则表示所有顶点均已输出,排序成功。
Error("G中存在有向环,排序失败!");
}
<pre name="code" class="cpp"> int graph[narray][narray]; //邻接阵 int indegree[narray]; //记录顶点的入度 int n; //n为顶点个数 memset(graph,0,sizeof(graph)); memset(indegree,0,sizeof(indegree)); for(i=1;i<=n;++i) //遍历n次每次找出一个顶点 { for(j=1;j<=n;++j) //遍历所有的结点 { if(indegree[j]==0) { indegree[j]--; //该顶点的入度为-1,防止该顶点被在此遍历到 if(i!=n) printf("%d ",j); else printf("%d\n",j); for(k=1;k<=n;++k) { if(graph[j][k]) indegree[k]--; //与该顶点关联的顶点的入度递减 } break; } } }
三、无后继的顶点优先的拓扑排序方法
1、思想方法
该方法的每一步均是输出当前无后继(即出度为0)的顶点。对于一个DAG,按此方法输出的序列是逆拓扑次序。因此设置一个栈(或向量)T来保存输出的顶点序列,即可得到拓扑序列。若T是栈,则每当输出顶点时,只需做人栈操作,排序完成时将栈中顶点依次出栈即可得拓扑序列。若T是向量,则将输出的顶点从T[n-1]开始依次从后往前存放,即可保证T中存储的顶点是拓扑序列。
2、抽象算法描述
算法的抽象描述为:
NonSuccFirstTopSort(G){//优先输出无后继的顶点
while(G中有出度为0的顶点)do {
从G中选一出度为0的顶点v且输出v;
从G中删去v及v的所有人边 }
if(输出的顶点数目<|V(G)|)
Error("G中存在有向环,排序失败!"); }
图结构练习——判断给定图是否存在合法拓扑序列Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^题目描述给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。输入输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)后面m行每行两个整数a b,表示从a到b有一条有向边。输出若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。示例输入1 02 21 22 1示例输出YESNO
1、无前趋的顶点优先的拓扑排序
#include<bits/stdc++.h> using namespace std; int ma[20][20],vis[20],out[20]; int n,m; void creat() //构建图 { int a,b,i; memset(ma,0,sizeof(ma)); memset(vis,0,sizeof(vis)); memset(out,0,sizeof(out)); for(i=1; i<=m; i++) { cin>>a>>b; if(ma[a][b]==0) { ma[a][b]=1; out[b]++; //存入每个节点的入度,入度++ } } } void qsort() { int i,f,k,j; for(i=1; i<=n; i++) { f=0; for(j=1; j<=n; j++) { if(vis[j]==0&&out[j]==0) //若该点未被访问过,且入度为0 { vis[j]=1; //标记该点已被访问过 for(k=1; k<=n; k++) { if(ma[j][k]==1) //找到入度为一的点 { out[k]--; //将入度减1,保证可以得到下一个输出点 } } f=1; break; } } if(f==0) break; } if(f==1) { printf("YES\n"); } else printf("NO\n"); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { creat(); qsort(); } return 0; }
2、无后缀的顶点优先拓扑排序
#include<bits/stdc++.h> using namespace std; int ma[20][20],vis[20],out[20]; int n,m; void creat() //构建图 { int a,b,i; memset(ma,0,sizeof(ma)); memset(vis,0,sizeof(vis)); memset(out,0,sizeof(out)); for(i=1; i<=m; i++) { cin>>a>>b; if(ma[a][b]==0) { ma[a][b]=1; out[a]++; //存入每个节点的出度,出度++ } } } void qsort() { int i,f,k,j; for(i=1; i<=n; i++) { f=0; for(j=1; j<=n; j++) { if(vis[j]==0&&out[j]==0) //若该点未被访问过,且出度为0 { vis[j]=1; //标记该点已被访问过 for(k=1; k<=n; k++) { if(ma[k][j]==1) //找到出度为一的点 { out[k]--; //将出度减1,保证可以得到下一个输出点 } } f=1; break; } } if(f==0) break; } if(f==1) { printf("YES\n"); } else printf("NO\n"); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { creat(); qsort(); } return 0; }
相关文章推荐
- scikit-learn(工程中用的相对较多的模型介绍):2.3. Clustering(可用于特征的无监督降维)
- 软件设计师自我修炼1:如何让用户对软件产生依赖
- android ContentProvider的使用
- 杭电ACM(HDUOJ)试题分类
- MeasureSpec学习
- 动态规划之背包问题
- 计算组合数C(n,m)
- Property list 概述
- 装饰者设计模式
- nyoj32组合数(dfs模板)
- 在Java中辅助报表工具展现json
- 轻松入门React和Webpack
- 线程(2)-----线程池
- 编写Socket客户端和服务器程序,客户端发送一个包含多个数字的字符串给服务器,服务器排序后返回给客户端,要求服务器能连续不断地服务。
- tableView联动
- HDU - 3715 Go Deeper (二分 + 2-SAT)
- linux下的解压命令详解
- 抓包函数-pcap_next
- 测量平差之间接平差
- 2015-8-10工作日志