聰聰研究發現,荒島野人總是過著群居的生活,但是,並不是整個荒島上的所有野人都屬於同乙個部落,野人們總是拉幫結派形成屬於自己的部落,不同的部落之間則經常發生爭鬥。只是,這一切都成為謎團了——聰聰根本就不知道部落究竟是如何分布的。
不過好訊息是,聰聰得到了乙份荒島的地圖。地圖上標註了n個野人居住的地點(可以看作是平面上的座標)。我們知道,同乙個部落的野人總是生活在附近。我們把兩個部落的距離,定義為部落中距離最近的那兩個居住點的距離。聰聰還獲得了乙個有意義的資訊——這些野人總共被分為了k個部落!這真是個好訊息。聰聰希望從這些資訊裡挖掘出所有部落的詳細資訊。他正在嘗試這樣一種演算法:
對於任意一種部落劃分的方法,都能夠求出兩個部落之間的距離,聰聰希望求出一種部落劃分的方法,使靠得最近的兩個部落盡可能遠離。
依次把兩個最近的人劃分到乙個部落中去(若其中乙個或兩個人還屬於其他部落,那麼這兩個部落合併),當最後剩下單獨的k個人和部落的時候,這時候這其中的,相距最近的兩個部落/部落和人的距離就是最重要的答案。
仔細觀察,其實這就是乙個最小生成樹,建n-k條邊的最小生成樹,第n-k+1條邊就是要的結果。
#include #include #include #include #include const int maxn = 1005;
struct edge
edge(int u, int v, double w):u(u), v(v), w(w){}
bool operator < (const edge &x) const
} e[maxn * maxn];
double a[maxn][2];
int tot = 0, father[maxn];
int find(int x)
void union(int u, int v)
}double getdis(int u, int v)
double kruskal(int nv, int k)
int t = 0;
double ans = 0;
for (int i = 0; i < tot; i++) }}
return ans;
}void solve()
for (int i = 0; i < n; i++)
}std::sort(e, e + tot);
double ans = kruskal(n, k);
printf("%.2f", ans);
}int main()
P4047 JSOI2010 部落劃分題解
題意 給定一些點,要把這些點分為k個部落,問最近兩個部落間的最遠距離是多少。解法 二分答案 並查集檢測鴨!二分的時候要注意精度問題噢,eps開到1e 3會有乙個點過不去。開始看錯題意想半天。include include include include include include include...
洛谷 P4047 JSOI2010 部落劃分
這道題其實就是無線通訊網的雙倍經驗啦,只是在輸出的時候不同罷了。還是一樣的 kruskal 演算法,但是在求的時候,應該在 now n k 1 的時候結束。本來到 n k 就行了的,但是由於 n k 1 這條邊是在應該部落裡面的,不能算,所以要找到第乙個不在乙個部落裡面的邊。include usin...
P4047 JSOI2010 部落劃分 並查集
思路 並查集 生成樹 提交 2次 雖然樣例都沒過但感覺是對的 qwq 判邊少了一條 題解 把所有點之間連邊,然後 sort 一遍,從小往大加邊,直到連第 n k 1 條邊 相當於是破話 k 個連通塊的最短邊 記錄權值即為答案。include include include include inclu...