dfs与bfs的很直接的应用就是拓扑排序。
拓扑排序如果用数组来模拟链表进行操作,既解决了稀疏图的空间问题,又解决了用链表进行操作麻烦的问题
但是拓扑排序并不是数字大小之间的排序,而是某些事情之间的顺序有着相互的顺序关系,就好比说你学了c语言基础以后再继续学习更高深的数据结构学完数据结构之后才能够去做一些比较难一些的算法题

第一个题 hdu3342 (基于bfs的拓扑排序)
HDU3342
给出一部分人的师徒关系,让我们来判断是否合法,比如说(1是2的师傅,2是1的师傅关系不合法)也就是可以理解为形成了自环,可以拓扑排序的要求是这个图是有向无环图,如果拓扑排序没有矛盾,也就是说所有结点都被遍历过,此时可以输出yes,可以用一个变量来记录一下是否全部遍历过,如果变量等于人数则输出yes

代码

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#define maxn  1000005
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
const double pi = acos(-1);
typedef long long ll;
ll mod;
using namespace std;
int n,m;
vector < vector<int> > imap;
int pre[1000];bool topsort(){queue <int> q;for(int i=0;i<m;i++){if(pre[i]==0)q.push(i);}int ans=0;while(!q.empty()){int temp=q.front();q.pop();ans++;for(int i=0;i<(int)imap[temp].size();i++){int x=imap[temp][i];pre[x]--;if(pre[x]==0){//     cout<<x<<" ";q.push(x);}}}//cout<<ans<<endl;return ans==m;
}int main()
{while(cin>>m>>n){if(m==0&&n==0)  break;int x,y;imap.clear();imap.resize(m+1);memset(pre,0,sizeof(pre));for(int i=0;i<n;i++){scanf("%d%d",&x,&y);imap[x].push_back(y);  pre[y]++;   //这个是用来记录与他相邻的点并且在他前面的点的个数}//  for(int i=0;i<m;i++) cout<<pre[i]<<" ";if(topsort())  cout<<"YES"<<endl;else  cout<<"NO"<<endl;}return 0;
}

第二题 poj1270 (基于bfs的拓扑排序) (按字典序输出-正向建图)
poj1270
这个题可能没有前面那个题容易,但是个人感觉蛮重要的,。
注意的几点:
(1)输入的字符之间有空格
(2)每组输出之间有一个空行
他既然要按字典序输出,我们可以提前将他排好序,然后挨个检验是否符合标准,字符x前面不能有字符y,就可以转化为拓扑排序来做,(也就是说当某个字母是入度为0的字母,我们就可以将他放进去,如果入度不为零,说明这个字符前面还有别的字符,如果我们放进去,输出的字符肯定会不合法)

//#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#define maxn  1000005
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
//const double pi = acos(-1);
typedef long long ll;
ll mod;
using namespace std;
int n,m,f;
int pre[1000];
int mp[300][300];
char put[100];
string s;
char s1[300];
int s2[300];
int x,y;void toposort(int steps){if(steps==f){printf("%s\n",put);return ;}for(int i=0;i<f;i++){if(pre[i]==0){//    cout<<i<<endl;pre[i]--;for(int j=0;j<f;j++)if(mp[i][j]==1)   pre[j]--;put[steps]=s1[i];toposort(steps+1);pre[i]++;           //回溯的思想for(int j=0;j<f;j++)if(mp[i][j]==1)    pre[j]++;}}return ;
}int main()
{//freopen("out.txt","w",stdout);while(getline(cin,s)){f=0;memset(mp,0,sizeof(mp));memset(pre,0,sizeof(pre));memset(s2,0,sizeof(s2));memset(s1,0,sizeof(s1));memset(put,0,sizeof(put));for(int i=0;i<s.size();i++){if(isalpha(s[i])){s1[f++]=s[i];}}sort(s1,s1+f);getline(cin,s);for(int i=0;i<f;i++){s2[s1[i]]=i;}bool flag=true;for(int i=0;i<s.size();i++){if(isalpha(s[i])){if(flag){flag=false;x=s[i];}else{flag=true;y=s[i];mp[s2[x]][s2[y]]=1;pre[s2[y]]++;}}}toposort(0);printf("\n");}return 0;
}

第三题HDU4857(基于bfs的拓扑排序)按编号排序-反向建图
HDU4857
这个题跟之前的的按照字典序输出有一定的区别
意思是说编号小的尽量在这一串的前面
我们直接用优先队列进行储存,让最大的数先出列,最后逆序输出就可以。

//#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#define maxn  1000005
//#define true false
//#define false true
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
//const double pi = acos(-1);
typedef long long ll;
ll mod;
using namespace std;
vector < vector<int> > vec;
vector <int>  put;
int n,m;
int pre[30010];
void toposort(){priority_queue<int,vector<int>,less<int> > q;for(int i=1;i<=n;i++){if(pre[i]==0){q.push(i);}}while(!q.empty()){int temp=q.top();q.pop();put.push_back(temp);for(int i=0;i<vec[temp].size();i++){int x=vec[temp][i];pre[x]--;if(pre[x]==0)  q.push(x);}}
}int main()
{int t;cin>>t;while(t--){cin>>n>>m;vec.clear();put.clear();vec.resize(n+1);memset(pre,0,sizeof(pre));for(int i=0;i<m;i++){int x,y;scanf("%d%d",&x,&y);vec[y].push_back(x);pre[x]++;}toposort();for(int i=put.size()-1;i>=0;i--){if(i==0)  printf("%d\n",put[i]);else  printf("%d ",put[i]);}}return 0;
}

数据结构-图论-拓扑排序模板题(hdu3342)(poj1270)(hdu4857)相关推荐

  1. 图论--拓扑排序--模板

    //字典序号最小 #include <cstdio> #include <cstring> #define MAXN 517 int G[MAXN][MAXN]; //路径 i ...

  2. 最短工期 (25 分)【拓扑排序模板】

    立志用最少的代码做最高效的表达 一个项目由若干个任务组成,任务之间有先后依赖顺序.项目经理需要设置一系列里程碑,在每个里程碑节点处检查任务的完成情况,并启动后续的任务.现给定一个项目中各个任务之间的关 ...

  3. Kahn拓扑排序模板

    Kahn拓扑排序模板 O(V+E) #include<bits/stdc++.h> using namespace std;typedef long long ll; const int ...

  4. 数据结构C++——拓扑排序

    数据结构C++--拓扑排序 文章目录 数据结构C++--拓扑排序 一.前言 二.拓扑排序的概念及作用 三.拓扑排序的实现 ①拓扑排序的实现原理 ②拓扑排序中FindInDegree()函数的实现 ③拓 ...

  5. 图论---拓扑排序的应用

    最近研究了几道图论的题目,都是图论入门的算法,用的比较多的就是拓扑排序,多用于有着先后顺序的题目,也可以用来判断环,做个小总结. 杂物 题目链接:杂务 - 洛谷 这一题需要计算最短的时间,利用了记忆化 ...

  6. 拓扑排序基础题——排序

    题目 由于公司在2013年的销售业务成绩优秀,公司总经理心情大好,决定给每位员工发奖金.公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少.于是总经理下令召开 m 方会谈.每位参加会谈的代 ...

  7. AcWing 848. 有向图的拓扑序列(拓扑排序模板)

    题面链接 https://www.acwing.com/problem/content/850/ 思路 对于一个有向图来说,只有无环有向图才有拓扑序列,也可以说一个无环有向图必然有拓扑序列,但是不唯一 ...

  8. 拓扑排序模板(Kahn算法和DFS实现)

    拓扑排序思想: Kahn模板:每次取出入度为0的顶点删掉,并删掉和该点有关的边,需要维护一个入度为0的队列或者栈 //Kahn算法,关键在于需要维护一个入度为0的顶点的集合 int n,m; int ...

  9. 2022.3.24 图论——拓扑排序算法

    文章目录 一.拓扑排序简介 二.例题 1.题目 2.分析 3.代码 一.拓扑排序简介 1.Topological Sorting,指的是一个DAG(Directed Acyclic Graph)即有向 ...

最新文章

  1. day19_MD5加密_Apache DBUtils_监听器 知识回顾
  2. 使用Chrome打开http://www.cutv.com/demo/live_test.swf页面时swf文件自动下载问题
  3. Springboot-application.properties
  4. android调用fragment的方法,AndroidX下使用Activity和Fragment的变化
  5. vantUI 自定义引入iconfont图标(3种风格)- 案例篇
  6. 用python画糖葫芦_python学习记录六
  7. 基于spring多数据源动态调用及其事务处理
  8. onready怎么加img_用插件VMarker在vue中给图片加标记
  9. 为什么Audition CC2017扫描不了电音插件,你需要这个工具
  10. Chrome浏览器查看Axure原型图文件,提示Axure RP Extension for Chrome
  11. sslv3 poodle漏洞 检测解决方法
  12. CCITT对媒体的分类
  13. matlab在电磁场方向,基于matlab的电磁场仿真与分析探究.pdf
  14. 国际贸易术语_Incoterm
  15. 我国东北虎种群增长迅速 但近交风险不容忽视
  16. 有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中
  17. 使用html2canvas保存html或者div内容为图片及自定义名称
  18. 【云原生 | Kubernetes 系列】----污点与容忍
  19. c++基础题:判断奇偶数
  20. 除留余数法构造哈希函数并用链地址法处理哈希冲突【C++实现】

热门文章

  1. Ubuntu18.04中pyhton默认版本从2.7换为3.x
  2. scrapy的几个文件属性
  3. 组原-OS-政治截图
  4. OSPF协议将其管理的网络划分为不同类型的若干区域(Area),其中标准区域特点是(64);存根区域(stub)的特点是(65)。【答案】C B
  5. klock 分布式锁重大更新
  6. 恩布企业IM,协同办公平台发布V1.24.2版本
  7. JSP简单标签带属性开发
  8. UI基础 - UIScrollView
  9. Oracle中的系统权限管理
  10. RadGrid使用技巧:从RadGrid获取绑定的值