题目大意:给一个有向图,判断是不是树!!!
思路:我一上来就想着图,用邻接矩阵还是邻接表存储,是bfs遍历还是dfs遍历!!! 思维僵化了,一上来就想到这!!!
但是,那么东西确实是硬功!! 空树也是树,读题要认真仔细!!!!
这道题就是让我们判断一个有向图是不是树! 那我们想一想图在什么情况下是树呢!!!!!
1.首先,没有环
2.其次,每个结点的入读不能大于1
3.最后,结点数=边数+1
数据结构:并查集!!!
对不并查集不了解的同学请先学习并查集!!!!
请想清楚!!!!!!
import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;
public class T {
private static final int SIZE = 10005;
private static boolean[] vis = new boolean[SIZE];
private static int father[] = new int[SIZE];
public static void inti() {//初始化
Arrays.fill(vis, false);
Arrays.fill(father, -1);
}
public static int find(int x) {//并查集的find()函数
return father[x] == -1 ? x : find(father[x]);
}
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int from, to;// 起点,终点
int numNode, numEdge;// 结点数,边数
boolean flag;// 是否是树的标志位!
int k = 1;
while (true) {// 总的数据循环
from = sc.nextInt();
to = sc.nextInt();
if (from == -1 && to == -1) {
break;
}
numNode = numEdge = 0;
flag = true;// 默认是树
inti();
while (true) {// 每一组的数据循环
if (from == 0 && to == 0) {
break;
}
if (flag) {// 如果还是树,就接着判断
numEdge++;
if (!vis[from]) {//记录该结点是否出现过
vis[from] = true;
numNode++;
}
if (!vis[to]) {<span style="font-family: Arial, Helvetica, sans-serif;">//记录该结点是否出现过</span>
vis[to] = true;
numNode++;
}
if (find(to) != to) {// 情况1:入度大于1,已经有结点指向to了
// !!!找某结点的发结点只能用find(to)
flag = false;
}
// 情况2:from和to构成环
if (find(from) == find(to)) {
flag = false;
}
if (flag) {
father[to] = find(from);//没有构成环的情况下,to的father为from的祖先
}
}
from = sc.nextInt();
to = sc.nextInt();
}
if (flag && (numNode == numEdge + 1 || numEdge == 0)) {//注意空树的情况!!!,我就因为没看到,WA了2次!!!
System.out.println("Case " + k + " is a tree.");
} else {
System.out.println("Case " + k + " is not a tree.");
}
k++;
}
sc.close();
sc = null;
}
}
上码: