浅谈 拓扑排序
我是什么時候想到要學拓撲排序的呢?
在一次模考的時候,有這樣一道題,叫做食物鏈,我是寫了記憶化搜索的,然而全場都寫了拓撲板子
后來發現我居然不會這么基礎的算法,有點慌
下面進入正題
拓撲排序是針對一些特殊問題的,類似于在完成某一件是之前,有必要條件,要先完成另外的一些任務
只有有向無環圖才有拓撲排序,這就關系到了定義
拓撲排序是先排入度為零的點,然后把所有的與之有關的邊都刪掉,這時就又會有一些如度為零的點出現
然以后循環上述操作
這就是拓撲排序的基本概念
還是舉個例子吧
如圖:
我們發現1的如度為零
所以先把1刪掉,把與1有關的邊刪掉
然后就發現2的入度變成了零
然后會重復上述操作
得到了這個圖的與拓撲排序:1? ?2? ?3? ?4? ?5
下面給出代碼:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> using namespace std; inline int min(int a,int b){return a<b?a:b;} inline int max(int a,int b){return a>b?a:b;} inline int rd() {int x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f; } inline void write(int x) {if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0'); } int n,m; int head[100006],nxt[100006],to[100006]; int in[100006]; int total=0; void add(int x,int y){//鄰接表存邊 total++;in[y]++;to[total]=y;nxt[total]=head[x];head[x]=total;return ; } int tot=0; int s[100006]; void topo(){for(int i=1;i<=n;i++) if(!in[i]) s[++tot]=i;//先找出已有的入度為零的點 for(int i=1;i<=tot;i++){for(int e=head[s[i]];e;e=nxt[e]){//刪除與其相關的邊 in[to[e]]--;if(!in[to[e]]) s[++tot]=to[e];//如果又出現入度為零的點,就入隊 }}return ; } int main() {n=rd(),m=rd();for(int i=1;i<=m;i++){int x=rd(),y=rd();add(x,y);//有向圖單向存邊 }topo();for(int i=1;i<=n;i++) printf("%d\n",s[i]);return 0; }
可算是填了坑QAQ
轉載于:https://www.cnblogs.com/WWHHTT/p/9716347.html
總結
- 上一篇: 川贝多少钱啊?
- 下一篇: CentOS 6.7快速搭建lamp环境