城市之间有单向公路连接,如果某个城市可以进来的城市数量大于出去可以到达的城市数量,则可以说明该城市是优良城市。(来自腾讯19届校招笔试题)
测试:第一行是城市数量n与公路数量m,下面是m行公路,每行两个数据,起始城市与到达城市
7 10
1 2
1 5
2 3
4 1
2 4
5 3
6 2
6 5
6 7
7 3
结果:
3 5
代码如下:
package y2018.m09.d16;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
public class bestCity {
static Scanner cin = new Scanner(System.in);
static List<directedEdge> dEdge = new ArrayList<directedEdge>();
static boolean[] isCome;
public static void main(String[] args) {
while (cin.hasNext()) {
HashSet<Integer> zhiqianList;
HashSet<Integer> zhihouList;
//城市数量
int n = cin.nextInt();
//判断成环的依据
isCome=new boolean[n+1];
//边的数量
int num = cin.nextInt();
for (int i = 0; i < num; i++) {
dEdge.add(new directedEdge(cin.nextInt(), cin.nextInt()));
}
for (int i = 1; i <= n; i++) {
zhiqianList = zhiqian(i);
for(int j=1;j<=n;j++){
isCome[j]=false;
}
zhihouList = zhihou(i);
for(int j=1;j<=n;j++){
isCome[j]=false;
}
if (zhiqianList.size() > zhihouList.size()) {
System.out.print(i + " ");
}
}
}
}
public static HashSet<Integer> zhiqian(int i) {
isCome[i]=true;
HashSet<Integer> set = new HashSet<Integer>();
HashSet<Integer> newset;
for (directedEdge e : dEdge) {
if (e.endToStart(i) != 0) {
if(!isCome[e.endToStart(i)]) {
set.add(e.endToStart(i));
isCome[e.endToStart(i)] = true;
}
}
}
if (set.size()!= 0) {
//遍历之前的集合,去间接到达的城市
HashSet<Integer> copyset=new HashSet<Integer>();
for (Integer k : set) {
newset = zhiqian(k);
if (newset.size() == 0) {
continue;
}
for (Integer j : newset) {
copyset.add(j);
}
}
for(Integer copy:copyset){
set.add(copy);
}
}
return set;
}
public static HashSet<Integer> zhihou(int i) {
isCome[i]=true;
HashSet<Integer> set = new HashSet<Integer>();
HashSet<Integer> newset;
for (directedEdge e : dEdge) {
if (e.startToEnd(i) != 0) {
if(!isCome[e.startToEnd(i)]) {
set.add(e.startToEnd(i));
isCome[e.startToEnd(i)] = true;
}
}
}
if (set.size()!= 0) {
//遍历之前的集合,去间接到达的城市
HashSet<Integer> copyset=new HashSet<Integer>();
for (Integer k : set) {
newset = zhihou(k);
if (newset.size() == 0) {
continue;
}
for (Integer j : newset) {
copyset.add(j);
}
}
for(Integer copy:copyset){
set.add(copy);
}
copyset.clear();
}
return set;
}
}
class directedEdge {
public int start;
public int end;
public directedEdge(int start, int end) {
this.start = start;
this.end = end;
}
public int endToStart(int i) {
if (end == i) {
return start;
}
return 0;
}
public int startToEnd(int i) {
if (start == i) {
return end;
}
return 0;
}
}