有向无环图DAG学习笔记
前言
重学DAG。 终于没有补档了……
Update
2024-10-16: 开坑。
正文
定义
顾名思义,有向无环图(Directed Acyclic Graph,DAG)就是边有方向,没有环的图。
拓扑排序(Topological sorting,Toposort),用于给DAG的所有结点进行排序,使得所有有向边
性质
图
拓扑排序算法
BFS(Kahn)
集合
每次从
时间复杂度为
Code
#include<bits/stdc++.h>
using namespace std;
int n;
int deg[110];
vector<int> h[105];
queue<int> q;
void topo()
{
for(int i=1;i<=n;i++)
{
if(deg[i]==0)
{
cout<<i<<" ";
q.push(i);
}
}
while(q.size())
{
int u=q.front();
q.pop();
for(int i=0;i<h[u].size();i++)
{
deg[h[u][i]]--;
if(deg[h[u][i]]==0)
{
cout<<h[u][i]<<" ";
q.push(h[u][i]);
}
}
}
}
int main()
{
cin>>n;
for(int u=1;u<=n;u++)
{
int v;
while(1)
{
cin>>v;
if(v==0)
break;
h[u].push_back(v);
deg[v]++;
}
}
topo();
return 0;
}
DFS
dfs不需要记录入度,因为其本身就是一个拓扑排序的过程,只需在每次回溯的时候记录节点,返回的序列就是反拓扑序,将其倒过来即可,时间复杂度为
Code
#include<bits/stdc++.h>
using namespace std;
int n;
bool vis[105];
vector<int> G[105];
stack<int> st;
void dfs(int u)
{
for(auto v:G[u])
{
if(vis[v])
continue;
dfs(v);
}
vis[u]=1;
st.push(u);
}
int main()
{
cin>>n;
for(int u=1;u<=n;u++)
{
int v;
while(1)
{
cin>>v;
if(v==0)
break;
G[u].push_back(v);
}
}
for(int i=1;i<=n;i++)
if(!vis[i])
dfs(i);
while(!st.empty())
{
cout<<st.top()<<" ";
st.pop();
}
return 0;
}
DAG最短(长)路
一般图的最短(长)路最优时间复杂度为Bellman_ford的
先进行拓扑排序,得出拓扑序
算法过水,代码就不给了。
结尾
感谢设计算法与实现代码的大神们。
本文算法资料来自OI-WIKI,在此特意声明,以示感谢。