Island 基環樹直徑

2022-05-19 06:24:14 字數 2307 閱讀 9561

《更新提示》

《第一次更新》

《正文》

你準備瀏覽乙個公園,該公園由 n 個島嶼組成,當地管理部門從每個島嶼 i 出發向另外乙個島嶼建了一座長度為 l_i 的橋,不過橋是可以雙向行走的。同時,每對島嶼之間都有一艘專用的往來兩島之間的渡船。相對於乘船而言,你更喜歡步行。你希望經過的橋的總長度盡可能長,但受到以下的限制:

注意,你不必遊覽所有的島,也可能無法走完所有的橋。

請你編寫乙個程式,給定 n 座橋以及它們的長度,按照上述的規則,計算你可以走過的橋的長度之和的最大值。

第一行包含 n 個整數,即公園內島嶼的數目。

隨後的 n 行每一行用來表示乙個島。第 i 行由兩個以單空格分隔的整數,表示由島 i 築的橋。第乙個整數表示橋另一端的島,第二個整數表示該橋的長度 l_i。你可以假設對於每座橋,其端點總是位於不同的島上。

僅包含乙個整數,即可能的最大步行距離。

7

3 87 2

4 21 4

1 93 4

2 3

24
很多年前的一道老題了,題意即為:給定基環樹森林,求各棵基環樹的直徑之和。

大體思路是這樣的,對於每一顆基環樹,可以先找到基環樹的環\(loop_\),設以\(loop_i\)為根的樹中,以\(loop_i\)為起點的最長鏈長度為\(deep_i\),該樹中的樸素直徑為\(diameter_i\),那麼這一棵基環樹的答案一定就是:

\[ans=\max

\begin

\max\

\\ \max\

\end

\]對於第乙個式子,我們直接用樹形\(dp\)求樹的直徑即可。

對於第二個式子,\(deep\)我們顯然可以直接\(dfs\)處理,然後我們斷環為鏈並複製一倍,\(path(loop_i,loop_j)\)的長度我們可以改為\(sum_j-sum_i\),那麼就是求

\[\max_\

\]把它當做\(dp\),列舉\(j\),單調佇列維護\(\)單調性即可。

然後累加每一棵基環樹的答案即可。

我的做題歷程和一些我犯過的錯誤:

然後就是還有乙個點是被卡常的,至於怎麼辦,我也不知道。

\(code:\)

#include#define mset(name,val) memset(name,val,sizeof name)

using namespace std;

const int n=1e6+10;

const long long inf=long_long_max;

int n,last[n*2],t;long long ans,deep[n*2],link[n*2],sum[2*n],f[n*2],ans_,f[n],d[n];

int dfn[n],a[n*2],loop[n],inloop[n],tot,cnt,fa[n],used[n],vis[n];

struct edgee[n*2];

inline void insert(int x,int y,long long v)

inline char getchar()

inline void readll(long long &k)

inline void read(int &k)

inline void input(void)

}inline void reset(void)

inline void find_loop(int u)

}} }

else

}} link[1]=v1;link[2]=v2;

a[1]=loop[1];a[2]=loop[2];

} for(register int i=tot+1;i<=2*tot;i++)

for(register int i=1;i<=tot*2;i++)

sum[i]=sum[i-1]+link[i];

}inline long long calc(int x)

inline long long dp(void)

{ deque < int > q;long long res=ans_;

q.push_back(1);res=max(res,deep[1]);

for(register int j=2;j<=2*tot;j++)

{ while(!q.empty()&&j-q.front()>=tot)q.pop_front();

f[j]=sum[j]+deep[j]+calc(q.front());

while(!q.empty()&&calc(q.back())

《後記》

樹的直徑,重心和基環樹(2019 2 3)

基本概念 樹的直徑 樹是圖論中的連通無環圖,樹上的任意兩點間的路徑是唯一的。樹上的任意兩點的距離是兩點間路徑的邊權和。而樹的直徑 假設為mp 是樹上的最長路徑,m,p兩點是樹上距離最遠的點。演算法 樹的直徑 兩次bfs或dfs 從樹上的的任意一點c出發找到離它最遠的乙個點a,再從點a開始尋找離它最遠...

ACWING 358 島嶼(基環樹直徑)

題意 你準備遊覽乙個公園,該公園由 n 個島嶼組成,當地管理部門從每個島嶼出發向另外乙個島嶼建了一座橋,不過橋是可以雙向行走的。同時,每對島嶼之間都有一艘專用的往來兩島之間的渡船。相對於乘船而言,你更喜歡步行。你希望所經過的橋的總長度盡可能的長,但受到以下的限制 可以自行挑選乙個島開始遊覽。任何乙個...

初識基環樹 gay環樹?

衢州飯店出鍋了?以為自己幸運,哪知無法逃過一劫。學個oi,菊花不保啊 霧。最近考了好多道關於基環樹 包括基環內向樹基環 外向樹 的題,趁機學一波 首先明確,基環樹不是樹。其是一顆樹 一條額外的邊,即一顆樹 乙個環。大致簡述一下這種特殊結構出現的主要原因就是n個點連出去n條邊,而樹是n點n 1條邊,這...