給你乙個圖,求乙個最大邊和最小邊差值最小的生成樹
首先我們可以列舉最小邊,每次跑乙個最小生成樹即可
但是這樣會超時,我們考慮優化
採用最優性剪枝,假設我們當前樹中的最小邊是i,當前邊是j,當前最優答案是ans,那麼對於所有邊k使得length(j)-length(k)>ans的邊在列舉最小邊的時候可以直接跳過,下一次直接從k+1開始列舉,這樣就可以優化時間複雜度,期望100分
當然這不是正解,正解好像是什麼lct維護的,可以自行搜尋
#include
#include
#include
using
namespace
std;
struct edge g[100010];
int n,m,ans=(1
<<31)-1,f[2010];
inline
bool c1(edge a,edge b)
int main() //這裡是整個演算法優化的核心
} if(cnt==n-1) ans=min(ans,tot); if(k>i) i=k; else ++i; //最優性剪枝
} if(ans==(1
<<31)-1) puts("-1"); else
printf("%d\n",ans);
}
似乎還有一種方法也可以ak,而且比上面的快很多:
在演算法二中,我們每次列舉後都重新求了最小生成樹,事實上這是不必要的。考慮從大到小列舉生成樹的最小邊,我們要做的實際上是每次加入一條邊,維護當前圖的最小生成樹。加入一條邊時,我們需要判斷這條邊能否與之前的邊構成環。
若能構成環,用該邊替代環中最大邊一定更優;i 若不能構成環,直接加入該邊即可。找環中最大邊可以用 dfs 實現。若圖中現有的邊數為 n − 1,我們就可以更新答案。時間複雜度 o(m log m + mn),期望得分 100 分
JZOJ 3806 小X 的道路修建
因為一場不小的 y 省n 個城市之間的道路都損壞掉了,省長希望小x 將城市之間的道路重修一遍。很多城市之間的地基都被 破壞導致不能修路了,因此可供修建的道路只有m 條。因為施工隊伍有限,省長要求用盡量少的道路將所有的城市連通起來,這樣施工量就可以盡量少。不過,省長為了表示自己的公正無私,要求在滿足上...
JZOJ5776 小x遊世界樹
description 小x得到了乙個小道訊息,傳說中的神島阿瓦隆在格陵蘭海的某處,據說那裡埋藏著亞瑟王的寶藏,這引起了小x的好奇,但當他想前往阿瓦隆時發現那裡只有聖誕節時才能到達,然而現在已經春天了,不甘心的他將自己的目的地改成了世界樹,他耗費了大量的時間,終於將自己傳送到了世界樹下。世界樹是一棵...
Jzoj3805 小X的二叉堆計數
題意 給你n個不同的數問你能構成多少個不同的二叉堆 顯然不能列舉,我們考慮用遞推 我們令f i 表示以i為根的二叉堆有多少種 令l,r為i的左右兒子,令size i 為以i為根的堆的大小 那麼顯然,f i f l f r c size i 1,size l 因為n個數互不相同,所以沒有重複 相當於是...