lanqiao OJ 108 发现环

简介: lanqiao OJ 108 发现环

1.发现环 - 蓝桥云课 (lanqiao.cn)

这是一个拓扑排序的题,用dfs找一下拓扑序列,因为找不到所以一定会有环,记录每一个点的前驱点,所求就是答案

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
 
using namespace std ;
const int N = 1e5 +10 ;
struct edge{//用于记录边
  int from , to ;
  edge(int a, int b){
    from = a , to = b ;
  }
};
int n ,cnt;//n是点的数量
bool v[N] ;//记录是否走过这个点
int path[N] ;//最后记录路径
int flag ;//记录一下是否找到环,找到环就退出dfs,要不然死循环
int fa[N] ;//记录每一个节点的前驱节点,便于后面路径的更新
vector<edge> e[N] ;//记录每一条边
 
void dfs(int u ,int pre){
  v[u] = 1 ;//凡是进来的点都标记一下,而且我们每一个点只会走一遍,如果走到第二遍就表示扎到了环
  for(int i = 0 ; i < e[u].size() ; i ++){
    int a = e[u][i].from , b = e[u][i].to ;//起点和终点
    if(b == pre){//因为是无向边所以我们不能再走上一个节点
      continue ;
    }
    fa[b] = a ;//记录一下当前这个点的父节点(前驱节点)
    if(v[b]){//如果找到走了第二次的点,就回溯记录路径
      int tmp = b ;
      flag = 1;//把旗帜标1 , 表示我们已经找到环了,马上退出dfs
      while(1){
        tmp = fa[tmp];
        path[cnt++] = tmp ;
        if(tmp == b) break ;
      } 
      return  ;
    } 
    else dfs(b,a) ;//没有找到环,继续深搜遍历每一个点
    if(flag == 1) return ;
  }
}
 
int main(){
  cin >> n ;
  for(int i = 0 ; i <n ; i ++){
    int a , b ; cin >> a >> b ;//无向图,所以要记录双向
    e[a].push_back(edge(a,b)) ;
    e[b].push_back(edge(b,a)) ;
  }
 
  dfs(1,0) ;
  sort(path,path + cnt) ;//从大到小排序 
  for(int i = 0 ; i < cnt ; i ++) {
    cout << path[i]<< " "  ;
  }
  cout << endl ; 
  return 0 ;
}
目录
相关文章
|
2月前
lanqiao OJ 1030 蓝肽子序列
lanqiao OJ 1030 蓝肽子序列
39 2
|
2月前
lanqiao OJ 1388 寒假作业
lanqiao OJ 1388 寒假作业
34 0
|
2月前
lanqiao OJ 689 四阶幻方
lanqiao OJ 689 四阶幻方
30 0
|
2月前
lanqiao OJ 3513 岛屿个数(2023省赛)
lanqiao OJ 3513 岛屿个数(2023省赛)
16 2
|
2月前
lanqiao OJ 649 算式900
lanqiao OJ 649 算式900
16 1
|
2月前
lanqiao OJ 389 摆花
lanqiao OJ 389 摆花
19 2
|
2月前
lanqiao OJ 664 方格填数
lanqiao OJ 664 方格填数
13 1
|
2月前
lanqiao OJ 229 迷宫与陷阱
lanqiao OJ 229 迷宫与陷阱
25 1
|
2月前
|
算法
lanqiao OJ 1366 spfa最短路
lanqiao OJ 1366 spfa最短路
26 0
|
2月前
lanqiao OJ 641 迷宫
lanqiao OJ 641 迷宫
34 0