POJ #2485 Highways MST中的最大邊權
阿新 • • 發佈:2018-02-24
前向星 script truct sca ont color sin scrip n)
Description
問題描述:鏈接
思路
題目很直接,容易看出建的圖是一張完全圖,需要求出圖中最小生成樹的最大邊權。由於數據上界已經定死了,那麽選擇用靜態鄰接表存建圖。由於圖是稠密圖,那麽求MST的話就選擇 prim 。
做完 POJ #2253 Frogger 變種Dijkstra 後再做這個就很有感覺了。其實prim中的核心操作就是記錄並更新點v到樹的最短距離,然後把所有最短距離之中的最小值選出,將該點其加入樹集。這個樹集與dijkstra中的點集是異曲同工的。
能用 scanf 的話盡量用 scanf 吧,比 cin 快很多。
#include<iostream> #includeView Code<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; voidaddEdge (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; }
POJ #2485 Highways MST中的最大邊權