拓扑排序
- 对于DAG内所有节点,生成的序列
- DAG内所有节点出现且仅出现一次
- 若u->v,则排序时u的位置在v前面
- 可用于判环
queue<int> q;
int in[maxn],p; //in[]:入度 p:计数器/指针
int topo[maxn]; //topo[]:拓扑序[把拓扑排序的序列放到topo数组中存储,使用拓扑序时直接调用topo数组]
bool toposort(int n) { //n为图中的节点数
for(int u=1;u<=n;u++) //遍历所有节点出度
{
for(int i=head[u];i;i=e[i].next) //邻接表(链式前向星)存图所使用的遍历
{
int v=e[i].to;
in[v]++; //u->v,所以v点入度+1
}
if(!in[u]) //若入度==0,则放入队列
{
q.push(u);
}
}
while(!q.empty())
{
int u=q.front(); //取出的节点顺序为topo序
q.pop();
topo[++p]=u;
if(p>n) return false; //若p>n,说明有环(拓扑序内的节点数一定与DAG中节点数相同)
for(int i=head[u];i;i=e[i].next) { //链遍历
int v=e[i].to;
in[v]--; //每一个与u相连的点入度-1
if (!in[v]) //若v入度为0,则v入队
{
q.push(v);
}
}
}
return true;
}