拓扑排序
kahn算法
#include <bits/stdc++.h>
const int maxn=100+5,maxm=1e4+5;
struct Node{int to;int next;}e[maxm];
int n,m,len,head[maxn],rd[maxn],a[maxn];
void Insert(int x,int y){
e[++len].to=y;e[len].next=head[x];head[x]=len;
}
void Kahn(){
std::stack<int> q;
for(int i=1;i<=n;++i)//入度为0的点进栈
if(!rd[i])q.push(i);
int cnt=0;//计算出栈点的个数
while(!q.empty()){
int u=q.top();q.pop();a[++cnt]=u;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;rd[v]--;//相当于删除u的邻接边
if(!rd[v])q.push(v);
}
}
if(cnt<n){//说明有环
printf("Cycle\n");return;
}
for(int i=1;i<=cnt;++i)
printf("%d ",a[i]);
}
void Solve(){
scanf("%d%d",&n,&m);//n个点m条边有向图
for(int i=1;i<=m;++i){
int x,y;scanf("%d%d",&x,&y);
Insert(x,y);rd[y]++;
}
Kahn();
}
int main(){
Solve();
return 0;
}
基于dfs的算法
#include <bits/stdc++.h>
const int maxn=100+5,maxm=1e4+5;
struct Node{int to;int next;}e[maxm];
int n,m,len,cycle,head[maxn],rd[maxn],vis[maxn];
std::stack<int>q;
void Insert(int x,int y){
e[++len].to=y;e[len].next=head[x];head[x]=len;
}
void dfs(int u){
if(cycle==1)return;//如果已经存在环强制退出
vis[u]=-1;//u设为灰点
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(!vis[v])dfs(v);
else if(vis[v]==-1){//此时v如果为灰点说明<u,v>是反向边
printf("Cycle\n");cycle=1;return;
}//return只能退出一个递归
}
vis[u]=1;q.push(u);//u变黑说明无路可走,进栈
}
void Solve(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
int x,y;scanf("%d%d",&x,&y);
Insert(x,y);rd[y]++;
}
for(int i=1;i<=n;++i)//有可能是非连通图
if(!rd[i])dfs(i);
if(cycle==0)//无环则输出拓扑排序
while(!q.empty()){
printf("%d ",q.top());q.pop();
}
}
int main(){
Solve();
return 0;
}

浙公网安备 33010602011771号