蓝桥练习 发现环(C语言版 拓扑)

问题描述  
小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。

不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。

为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?输入格式  第一行包含一个整数N。

以下N行每行两个整数a和b,表示a和b之间有一条数据链接相连。

对于30%的数据,1 <= N <= 1000

对于100%的数据, 1 <= N <= 100000, 1 <= a, b <= N

输入保证合法。输出格式  按从小到大的顺序输出在环路上的电脑的编号,中间由一个空格分隔。
  
样例输入

5
1 2
3 1
2 4
2 5
5 3

样例输出

1 2 3 5

解题思路
由题意我们知道了是要在里面找一个环,里面有且只有一个环,所以我们可以结合拓扑排序的一点点知识,先把这个图放进一个类似邻接链表的数组里面,由于C语言没用vector这样的结构,所以我只能自己设置一个很大的二维数组来模拟,可变数组,a[i][0] 里面放关于这个点的度,我们把这个图里面凡是度为1的节点进行删除,最后不能删除的就是这个环上的节点,环节点的度为2。代码十分简单,下面直接上代码。

#include 
int a[100001][100];
void Find(int n){
 int x = 1;
 int i ,j , k;
 while(1){
  x = 1;
  for(i = 1; i <= n ; i ++){
   if( a[i][0] == 1){ //度为1就删除 并且把邻接点的度减1
    a[i][0] --; 
    a[ a[i][1] ][0] --;
     x=0;
   } 
  }
  if( x==1 ) break; //退出条件 如果没有度为1的点就退出这个死循环
 } 
}
int main(){
    int n, x, y,i, j ,k;
    scanf( "%d", &n );
    for( i = 0; i < n; i++ ) {
        scanf( "%d %d", &x, &y );
     	a[x][ ++a[x][0] ]=y; 
     //这个用来模拟可变数组 a[x][0] 用来表示该节点的度
        a[y][ ++a[y][0] ]=x;
    }
 Find(n);
 for( i = 1;i <= n ; i++){
   if( a[i][0]>1 )  printf("%d ",i);
  } 
 return 0;
}

你可能感兴趣的:(蓝桥杯练习题,蓝桥,C语言)