題目大意:給一個有向圖,判斷是不是樹!!!
思路:我一上來就想着圖,用鄰接矩陣還是鄰接表存儲,是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;
}
}
上碼: