給定 N 個城鎮座標與 M 條已建公路。需新建公路使所有城鎮連通,且新建公路總長度最小。輸出需新建的公路邊 (兩端城鎮編號)。
此題本質是求最小生成樹 (MST)。已建公路視為權重為 0 的邊。使用 Prim 演算法從任意點 (如 1) 開始擴展:
dis[i] 為點 1 到各點的距離平方 (或已建公路為 0)。dis 最小的點 u 加入。pre[u], u)。dis:dis[v] = min(dis[v], dist(u,v))。N ≤ 750,鄰接矩陣 O(N^2) Prim 適用 (約 56 萬次操作)。int dist2(int i, int j) {
return (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);
}
void prim() {
// 初始化 dis, pre
for (int i = 1; i <= n; ++i) {
dis[i] = g[1][i];
pre[i] = 1;
}
mark[1] = true;
for (int iter = 1; iter < n; ++iter) {
int u = -1, minD = INF;
for (int i = 1; i <= n; ++i)
if (!mark[i] && dis[i] < minD) { minD = dis[i]; u = i; }
if (minD != 0) printf("%d %d\n", pre[u], u); // 輸出新建公路
mark[u] = true;
for (int v = 1; v <= n; ++v)
if (!mark[v] && dis[v] > g[u][v]) {
dis[v] = g[u][v];
pre[v] = u;
}
}
}