白駿1197号最小生成ツリー
11439 ワード
🛠 デザイン
生成ツリーとは、図形から一部の幹線を選択して作成したツリーです.
ここで、最小生成ツリー(MST)とは、生成ツリーで選択された幹線の重み付けが最小となるツリーである.
通常、ネットワーク(通信、道路、ガスパイプ)を構成(接続)する際の最低コストに主に使用されます.
MSTを解く方法には古典的なKruskalアルゴリズムとPrimアルゴリズムがある.
この問題の最大頂点数は10000個,最大幹線数は100000個であり,密集型の複数の幹線のパターンが現れる確率が高いため,Primアルゴリズムを用いるのが適切である.
💻 コード#コード#
グラフィック設定
Graph g = new Graph(V);
for(int i = 0; i < E; ++i){
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
g.addEdge(new Edge(a, b, w));
g.addEdge(new Edge(b, a, w));
}
必要な資料構造。
PriorityQueue<Edge> pq = new PriorityQueue<>(); // 가중치가 최소인 간선을 도출하기 위한 우선 순위 큐
Queue<Integer> queue = new LinkedList<>(); // MST를 구성하는 정점 후보를 담고 있는 queue
boolean[] visited = new boolean[V + 1]; // 정점 방문 체크 배열
プリフェッチアルゴリズム
queue.add(1); // 시작 단계에서 한 정점을 기준으로 잡아준다.
while(!queue.isEmpty()){
int minV = queue.poll();
visited[minV] = true;
// 정점 minV와 간선으로 연결된 곳 중 방문하지 않은 정점을 우선 순위 큐에 추가
for(Edge e : g.edgeList[minV]){
if(!visited[e.end]) pq.add(e);
}
while(!pq.isEmpty()){
// minE는 가중치가 가장 작은 간선
Edge minE = pq.poll();
//간선 minE의 목적지가 아직 방문하지 않은 곳이라면
if(!visited[minE.end]){
// MST를 구성하는 정점 후보에 minE의 목적지를 담고 가중치 총 합에 가중치를 더해준다.
queue.add(minE.end);
visited[minE.end] = true;
sum += minE.weight;
break;
}
}
}
System.out.println(sum);
📝 ポスト
最初はQueueを使うとは思わなかったので、cntという変数、cnt
for(Edge e : g.edgeList[minV]){
if(!visited[e.end]) pq.add(e);
}
新しい最小ウェイトが更新される可能性があるため、ループで初期化できません.その問題を意識せずに見て答えを見ただけですが、これは最小生成木を使った最も基本的な問題で、勉強すればいろいろなところに応用できるはずです.
Reference
この問題について(白駿1197号最小生成ツリー), 我々は、より多くの情報をここで見つけました https://velog.io/@ybell1028/백준-1197번-최소-스패닝-트리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol