衢州飯店出鍋了?以為自己幸運,哪知無法逃過一劫。學個oi,菊花不保啊(霧。最近考了好多道關於基環樹(包括基環內向樹基環 外向樹)的題,趁機學一波
首先明確,基環樹不是樹。其是一顆樹+一條額外的邊,即一顆樹+乙個環。大致簡述一下這種特殊結構出現的主要原因就是n個點連出去n條邊,而樹是n點n-1條邊,這會恰好構成乙個環(由於是n個點n條邊,所以,有且僅有乙個!)。
但為什麼我們稱其為「樹」呢?主要就是我們只要略加修改其就可以當作一顆樹來做圖論(動歸)等等,而樹由於其優越的結構-->兩點間僅有一條路徑,可以完成很多事情。
將基環樹拆分開成環和樹兩部分處理,重要的就是環這一部分。我們發現,如果我們將基環樹環的一條邊切開,那麼這就構成了一顆樹!我們可以很好的將這個切邊的方法進行利用。
一道基環樹板子題 bzoj1040.
簡述:n點n邊,乙個點選就不能選和他相鄰的點,每個點有權值,求選出的最大權值。
原題雖然看似是有向邊事實上乙個人討厭另乙個人,那麼兩人只能選其一。由於不滿足兩兩之間一定到達,他就構成了乙個基環樹森林。
如果是樹 dp,dp方程同上司的舞會;dp[i][0]不選這個點其子樹最大權值,dp[i][1]選這個點其子樹最大權值
dp[i][0] += max(dp[son][1],dp[son][0]) dp[i][1] = val[i] += dp[son][0]
對於每一顆基環樹我們考慮切割一條邊。然後分別從這兩個切割的點當根開始跑dp,由於從這兩個點跑出去的dp不受限制,可能會出現選擇了對方點的情況,所以我們只能各取一方的dp[x][0]取乙個最大值加入答案。
code:
#include#include#include#includeusing namespace std;基環內向樹:基環內向樹事實上是一種有向圖。其結構模樣和基環樹一樣,只是他作為有向圖所有樹上邊都往環上走,也就是說任何在基環內向樹上任意點出發都可以到達環上。const int maxn = 2000005;
int n;
int jpoint1,jpoint2,jzb;
int en[maxn],nt[maxn],la[maxn],owo=1;
long long val[maxn];
void addedge(int a,int b)
long long dp[maxn][2];//dp[i][0] xuan dp[i][1] buxuan
bool vis[maxn];
void dfs(int x,int ba)
if(vis[en[it]])
else dfs(en[it],x); }}
void getdp(int x,int ba)
}long long ans;
int main()
for(int i=1;i<=n;i++) }
printf("%i64d",ans);
}
內向樹得題:zroi花園
基環外向樹:和內向樹很像,只是這裡是環上和樹上的點都能向外到樹的葉子結點上。
基環樹小結
持續更新ing 圖 的環顯而易見,一般的初始化流程有兩個 1 找環 void get ring ll u,ll fa cf835f 題目大意 刪掉一條邊,在保持聯通性的基礎上求最小直徑 既然要保持連通性,就只能考慮在環上刪邊 先將環中的每個節點子樹最大直徑求出 不跨過環 ll get d ll u,...
基環樹略解
基環樹,也叫環套樹,是一種圖的型別。如果連通圖 g g g 有 v e v e v e 則我們稱它是基環樹。顧名思義,基環樹就好似是在一棵樹上加一條邊得到的圖。基環樹有且僅有乙個環,所以也被成為環套樹。如上圖所示的圖就是一棵基環樹。基環樹沒什麼用。它只能解決部分特殊問題,而這類問題通常會註明 邊數 ...
約會 Rendezvous 基環樹
提煉 tarjan判環,dfs建樹,倍增lca,預處理環兩點間距離 我犯的錯誤 1.基環樹不只有一棵,可以有很多 2.自環不能將其忽略,對於我的演算法 應該將其特殊考慮在演算法內 3.一定要簡潔有力,不能讓自己調都噁心 code 陣列含義 que n 佇列,in que n tarjan判是否入隊,...