1. 程式人生 > >POJ #2485 Highways MST中的最大邊權

POJ #2485 Highways MST中的最大邊權

前向星 script truct sca ont color sin scrip n)

Description


  問題描述:鏈接

思路


  題目很直接,容易看出建的圖是一張完全圖,需要求出圖中最小生成樹的最大邊權。由於數據上界已經定死了,那麽選擇用靜態鄰接表存建圖。由於圖是稠密圖,那麽求MST的話就選擇 prim 。

  做完 POJ #2253 Frogger 變種Dijkstra 後再做這個就很有感覺了。其實prim中的核心操作就是記錄並更新點v到樹的最短距離,然後把所有最短距離之中的最小值選出,將該點其加入樹集。這個樹集與dijkstra中的點集是異曲同工的。

  能用 scanf 的話盡量用 scanf 吧,比 cin 快很多。

技術分享圖片
#include<iostream>
#include
<algorithm> #include<queue> #include<cstring> #include<cstdio> using namespace std; #define INF 0x3f3f3f3f const int MAXN = 510; const int EDGE_MAXN = 250010; int n; //鏈式前向星 struct Edge { int to; int w; //2^31-1 > 65536 int next; }e[EDGE_MAXN]; int head[MAXN], cnt; void
addEdge (int u, int v, int w) { cnt++; e[cnt].to = v; e[cnt].w = w; e[cnt].next = head[u]; head[u] = cnt; } void initG() { memset(head, -1, sizeof(head)); cnt = 0; scanf ("%d", &n); for (int i = 1; i <= n; i++) { int tmp; for (int j = 1; j <= i-1
; j++) { scanf ("%d", &tmp); addEdge(i, j , tmp); } scanf ("%d", &tmp); // i = j 形成自環,對建圖並沒有用 for (int j = i+1; j <= n; j++) { scanf ("%d", &tmp); addEdge(i, j, tmp); } } } //求最小生成樹的最大邊權 struct Node{ int id; int key; Node(int v, int w) : id(v), key(w) {} friend bool operator < (const Node& a, const Node& b) { return a.key > b.key; } }; int d[MAXN]; //v到樹的最短距離估計值 int vis[MAXN]; void prim (const int& s, int& max) { for (int i = 1; i <= n; i++) d[i] = INF, vis[i] = false; d[s] = 0; priority_queue <Node> pq; pq.push(Node(s, d[s])); while (!pq.empty()) { int u = pq.top().id; pq.pop(); if (vis[u]) continue; vis[u] = true; if (max < d[u]) max = d[u]; for (int i = head[u]; i != -1; i = e[i].next) { int v = e[i].to; if (!vis[v] && d[v] > e[i].w) { d[v] = e[i].w; //更新v到樹的最短距離 pq.push (Node(v, d[v])); } } } } int main(void) { int case_num; cin >> case_num; while (case_num--) { initG(); int ans = 0; prim(1, ans); printf ("%d\n", ans); } return 0; }
View Code

POJ #2485 Highways MST中的最大邊權