首先需要了解什麼是最小生成樹,還要知道什麼是倍增(求lca).
上面的東西如果了解了,就可以開始進入學習的路途了!!
用不是最小生成樹上的邊去更新答案.
對於每乙個倍增跳上去的,要維護兩個東西:
我們考慮一下對於每一條邊(不在最小生成樹上),如果要把它加入答案,如何更新?
mst-路徑最大值+邊權.
然後這個東西就可以很愉快地解決了...
其實不是的,如果題目求的是次小生成樹,這題就沒了,但是題目要求的是嚴格次小生成樹,怎麼辦呢?
考慮一下,如果要這樣子,我們更新答案就不能和mst相等,然後依舊可以很愉快地解決了!!!
#include#include#include#include#includeusing namespace std;
#define int long long
const int n=100010,m=300010,inf=2e18+10;
struct nodee[m];
int fa[n],front[n],to[n<<1],nxt[n<<1],w[n<<1],mst,cnt,n,m,k,flag[m];
int f[n][20],min[n][20],max[n][20],dep[n];
int find(int x)
void add(int u,int v,int w)
bool cmp(node a,node b)
int qmax(int u,int v,int w)
return ans;
}signed main();
}sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;i++)
}min[1][0]=-inf;
dep[1]=1;
dfs(1,-1);
for(int j=1;j<=18;j++)
for(int i=1;i<=n;i++)
int ans=inf;
for(int i=1;i<=m;i++)
if(!flag[i])
printf("%lld\n",ans);
return 0;
}
嚴格次小生成樹
顧名思義。生成樹,邊權和嚴格小於最小生成樹 一定和最小生成樹有關係。實際上,有 結論1 嚴格次小生成樹只在最小生成樹上改動一條邊 證明 改動一條邊有意義的話,必然改完這條邊,總和變大。那麼這至少是嚴格次小生成樹的最大值。再改一條也沒有意義。結論2 改動的那條邊w,一定是新加入的那條邊覆蓋的樹鏈的最大...
瘋子的演算法總結11 次小生成樹 嚴格次小生成樹
首先,我這一題的思路是倍增lca kruskal 首先,kruskal求最小生成樹 不會的戳這裡 求次小生成樹 倍增 lca 關鍵在於次小生成樹怎麼求 問自己一些問題 怎麼求不嚴格次小生成樹 不嚴格次小生成樹為什麼不嚴格 方法每次選擇u v之間的邊,前提是最小生成樹上不存在的邊,添邊之後刪去較短邊,...
嚴格次小生成樹學習筆記
嚴格次小生成樹,顧名思義,就是在聯通圖上選擇一些邊構成一棵樹,使這棵樹邊權和嚴格次小。要求嚴格次小生成樹,我們就要先求出最小生成樹 prim 和 kruskal 等演算法都可以,我用的是 kruskal 在求最小生成樹的過程中,還要給每條使用過的邊打乙個標記,如下 inline void krusk...