前言:这道题其实是另一道题的一个变形,如果觉得有点难度的话可以先去看着道题:https://blog.csdn.net/weixin_41549033/article/details/90083779
问题描述
小明的实验室有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
题解
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main{
static int[] par,vis,ret;
static int n,s,f;
static List<Integer>[] edge;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 输入边的数量
// 初始化各数组
par = new int[n+1];
vis = new int[n+1];
ret = new int[n+1];
edge = new ArrayList[n+1];
// 为par数组赋初值和并逐个初始化edge数组
for(int i=0;i<=n;i++){
par[i] = i;
edge[i] = new ArrayList<Integer>();
}
for(int i=1;i<=n;i++){
int u = sc.nextInt(); // 输入边的起点
int v = sc.nextInt(); // 输入边的终点
int ru = findRoot(u); // 找到u的根起点
int rv = findRoot(v); // 找到v的根起点
if(ru==rv) {
s = u; // 环路的起点
f = v; // 环路的终点
} else { // 根起点不同
par[ru] = rv; // 更改前驱
edge[u].add(v); // 在对应顶点的list中添加与之相连的顶点
edge[v].add(u);
}
}
dfs(s,0);
}
private static void dfs(int u, int ind) {
ret[ind] = u;
if(u==f){
Arrays.sort(ret,0,ind+1);
for(int i = 0; i < ind; i++)
System.out.print(ret[i]+" ");
System.out.println(ret[ind]);
return;
}
vis[u] = 1;
for(int i = 0; i < edge[u].size(); i++) {
int v = edge[u].get(i);
if(vis[v]==0) dfs(v, ind+1);
}
vis[u] = 0;
}
private static int findRoot(int x) { // 找到顶点x的根顶点
if(par[x]==x)
return x;
return findRoot(par[x]);
}
}
不过这种解法用c++写的话是可以100%的通过率的,但是用java的话只有30%。