CF E2 - Daleks' Invasion (medium) (LCA求两点树上路径上的最大边权)
生活随笔
收集整理的這篇文章主要介紹了
CF E2 - Daleks' Invasion (medium) (LCA求两点树上路径上的最大边权)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://codeforces.com/contest/1184/problem/E2
題意:給出一副圖,首先求出這幅圖的最小生成樹 , 然后修改這幅圖上不屬于最小生成樹的邊權,使得修改后的圖在求一邊生成樹的時候可以包含被修改的邊(注意:修改的邊權要最大 )題目規定只有一課生成樹
?
分析:
現在我們需要解決所有非樹邊的任務(MST保證是惟一的)。我們要求對于非樹邊(u, v),正確答案是u和v之間路徑上的最大權值MST。(證明:≤:由MSTs的循環特性可知;≥:如果(u, v)的重量大于這個最大值,然后用(u, v)交換獲得最大值的邊,會得到一個更便宜的樹a矛盾。
所以現在我們的任務就是求任意兩點在生成樹上的路徑最大邊權。這題我們可以用LCA的思想去完成,我們現在預處理出了一條路上走過的最大值,那么答案所求mx=max(mx(u->w) , mx(v->w)) ;w為u,v的最近公共祖先,這里采用倍增法的思想去完成
#include<bits/stdc++.h> using namespace std ; int n,m; const int maxn = 1e6+3; vector<pair<int,int> >G[maxn]; int pre[maxn],fa[maxn][19],dep[maxn],mx[maxn][19],ans[maxn]; struct no {int id,u,v,w; }a[maxn]; bool cmp(no a , no b) {return a.w<b.w; } int ffind(int x) {if(pre[x]==x) return x;pre[x]=ffind(pre[x]);return pre[x]; } void dfs(int u , int p) {for(int i=0 ; i<G[u].size() ; i++){int v=G[u][i].first;if(p==v) continue;dep[v]=dep[u]+1;fa[v][0]=u;mx[v][0]=G[u][i].second;dfs(v,u);} } int lca(int u , int v) {if(dep[u]>dep[v]) swap(u,v);for(int i=0 ; i<18 ; i++)if((dep[v]-dep[u])&(1<<i)) v=fa[v][i];if(u==v) return u;for(int i=17 ; i>=0 ; i--)if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];return fa[u][0]; } int ask(int u , int st) {int ret=0;for(int i=0 ; i<18 ; i++)if(st&(1<<i)) ret=max(ret,mx[u][i]),u=fa[u][i];return ret; } int main() {scanf("%d%d",&n,&m);for(int i=0 ; i<m ; i++){a[i].id=i;scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);}///卡魯思for(int i=1 ; i<=n ; i++) pre[i]=i;sort(a,a+m,cmp);for(int i=0 ; i<m ; i++){int u=ffind(a[i].u) , v=ffind(a[i].v);if(u!=v){pre[u]=v;ans[a[i].id]=-1;G[a[i].u].push_back({a[i].v,a[i].w});G[a[i].v].push_back({a[i].u,a[i].w});}}///lcadep[1]=1; dfs(1,0);for(int i=1 ; i<18 ; i++)for(int j=1 ; j<=n ; j++){fa[j][i]=fa[fa[j][i-1]][i-1];mx[j][i]=max(mx[j][i-1],mx[fa[j][i-1]][i-1]);}for(int i=0 ; i<m ; i++)if(ans[a[i].id]!=-1){int u=a[i].u ,v=a[i].v , w=lca(u,v);ans[a[i].id]=max(ask(u,dep[u]-dep[w]),ask(v,dep[v]-dep[w]));}for(int i=0 ; i<m ; i++){if(ans[i]!=-1)printf("%d ",ans[i]);} } View Code?
轉載于:https://www.cnblogs.com/shuaihui520/p/11150481.html
總結
以上是生活随笔為你收集整理的CF E2 - Daleks' Invasion (medium) (LCA求两点树上路径上的最大边权)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 兆邦·1018瓷砖贵吗?
- 下一篇: 是楚楚顶墙开创了顶墙门柜一体化轻定制吗?