POJ2367(拓撲序列入門_JAVA程式碼)
阿新 • • 發佈:2019-02-19
這個題是一道很明顯的拓撲序列入門題,直接套用拓撲序列模板即可。依次刪除掉入度為0的結點並輸出即可AC。
先找到一個入度為0的結點,然後刪除它,並把它所有後繼結點的入度減一,依次類推下去。直到找不到入度為0的結點或是所有點都刪除完
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Main {
private int N;
private Graph g;
private Scanner in;
private List<Integer> list;
public Main() {
in = new Scanner(System.in);
N = in.nextInt();
g = new Graph(N);
list = new ArrayList<Integer>();
for (int start = 1; start <= N; start++) {
int end;
while ((end = in.nextInt()) != 0) {
g.createAdj(start, end);
}
}
bfs();
for(int i=0;i<list.size();i++) {
System.out.print(list.get(i)+" ");
}
System.out.println();
}
//關鍵程式碼,用bfs實現的
private void bfs() {
//會bfs的人應該都知道,bfs是用佇列來實現的
Deque<Integer> queue = new LinkedList<Integer>();
//將入度為0的結點儲存到佇列中
for (int i = 1; i <= g.vertexNum; i++) {
if (g.inDeg[i] == 0) {
queue.offer(i);
}
}
//刪除入度為0的結點並把它的後繼結點入度減一
while (!queue.isEmpty()) {
int vertex = queue.poll();
//儲存拓撲序列的各個點
list.add(vertex);
for (int i = 0; i < g.adjacency[vertex].size(); i++) {
int u = g.adjacency[vertex].get(i);
if (--g.inDeg[u] == 0) {
queue.offer(u);
}
}
}
}
public static void main(String[] args) {
new Main();
}
}
//建立一個圖的資料結構
class Graph {
//圖的頂點數
int vertexNum;
//各個定點的名稱
int[] vertex;
//鄰接表
List<Integer>[] adjacency;
//各個頂點的入度,方便在構建拓撲序列的時候使用
int[] inDeg;
public Graph(int vertexNum) {
this.vertexNum = vertexNum;
vertex = new int[vertexNum + 1];
adjacency = new List[vertexNum + 1];
inDeg = new int[vertexNum + 1];
for (int i = 1; i <= vertexNum; i++) {
vertex[i] = i;
adjacency[i] = new LinkedList<Integer>();
}
}
void createAdj(int start, int end) {
//建立鄰接表
adjacency[start].add(end);
//標記入度
inDeg[end]++;
}
}