判定图中存在回路java_算法笔记_147:有向图欧拉回路判断应用(Java)

1 问题描述

Description

In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

Input

The first line contains a single integer T, the number of test cases. And followed T cases.

The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.

Output

The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.

Sample Input

1

3 3

1 2

2 3

3 1

Sample Output

Yes

Source

2 解决方案

具体代码如下:

packagecom.liuzhen.practice;importjava.util.ArrayList;importjava.util.Scanner;importjava.util.Stack;public classMain {public static int n; //顶点数

public static intcount;public static int[] DFN;public static int[] Low;public static boolean[] inStack;public static int group; //强连通分量组

public static int[] belong;public static Stackstack;public static ArrayList[] map;public static ArrayList result = new ArrayList();static classedge {public inta;public intb;public edge(int a, intb) {this.a =a;this.b =b;

}

}

@SuppressWarnings("unchecked")public voidinit() {

count= 1;

DFN= new int[n + 1];

Low= new int[n + 1];

inStack= new boolean[n + 1];

group= 0;

belong= new int[n + 1];

stack= new Stack();

map= new ArrayList[n + 1];for(int i = 1;i <= n;i++) {

DFN[i]= -1;

Low[i]= -1;

inStack[i]= false;

belong[i]= -1;

map[i]= new ArrayList();

}

}public void TarJan(intstart) {

DFN[start]= count++;

Low[start]=DFN[start];

inStack[start]= true;

stack.push(start);int j =start;for(int i = 0;i < map[start].size();i++) {

j=map[start].get(i).b;if(DFN[j] == -1) {

TarJan(j);

Low[start]=Math.min(Low[start], Low[j]);

}else if(inStack[j]) {

Low[start]=Math.min(Low[start], DFN[j]);

}

}if(DFN[start] ==Low[start]) {

group++;do{

j=stack.pop();

belong[j]=group;

inStack[j]= false;

}while(j !=start);

}

}public boolean TopSort(ArrayList[] lessMap, int[] degree) {int count = 0;

Stack s = new Stack();for(int i = 1;i < degree.length;i++) {if(degree[i] == 0) {

count++;

s.push(i);

}

}if(count > 1)return false;while(!s.empty()) {int start =s.pop();

count= 0;for(int i = 0;i < lessMap[start].size();i++) {int j =lessMap[start].get(i).b;

degree[j]--;if(degree[j] == 0) {

count++;

s.push(j);

}

}if(count > 1)return false;

}return true;

}

@SuppressWarnings("unchecked")public voidgetResult() {for(int i = 1;i <= n;i++) {if(DFN[i] == -1)

TarJan(i);

}

ArrayList[] lessMap = new ArrayList[group + 1];int[] degree = new int[group + 1];for(int i = 1;i <= group;i++)

lessMap[i]= new ArrayList();for(int i = 1;i < map.length;i++) {for(int j = 0;j < map[i].size();j++) {int a =map[i].get(j).a;int b =map[i].get(j).b;if(belong[a] !=belong [b]) {

lessMap[belong[a]].add(newedge(belong[a], belong[b]));

degree[belong[b]]++;

}

}

}if(TopSort(lessMap, degree)) {

result.add("Yes");

}else{

result.add("No");

}return;

}public static voidmain(String[] args) {

Main test= newMain();

Scanner in= newScanner(System.in);int t =in.nextInt();while(t > 0) {

t--;

n=in.nextInt();int k =in.nextInt();

test.init();for(int i = 0;i < k;i++) {int a =in.nextInt();int b =in.nextInt();

map[a].add(newedge(a, b));

}

test.getResult();

}for(int i = 0;i < result.size();i++)

System.out.println(result.get(i));

}

}

运行结果:

1

3 3

1 2

2 3

3 1Yes

参考资料:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值