zoj3820 樹的直徑 二分

2022-05-15 04:43:22 字數 1557 閱讀 8968

這題是個遺憾 !!!!!當時一直不敢相信兩個站一定在直徑上,賽後想想自己真的是腦袋抽風, 如果其中乙個站不在直徑上就反向的說明了這條不是直徑。可以很明白我們可以肯定的是有乙個點一定在直徑上假如另外乙個點不在直徑上,那麼他在分支上,那麼可以知道直徑上的某點一定大於這個分支的最遠點,顯然放在這個分支上是不合適的。好現在我們知道了者兩個點一定在直徑上,二分可能最小的距離,

求直徑 先從乙個點 bfs到離他最遠的點a ,然後從a bfs 到離他 最遠的點b ,然後 記錄路徑,就得到了 ab為直徑上的樹,那麼現在將每個直徑上的點進行bfs得到了算以他為根的分支最遠點(不算直徑),然後每次二分後,從直徑的兩段朝中間走,知道走到二分的答案,然後判斷可不可行, 我i好渣,當時腦袋真的被抽風了!

#include #include 

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 200005

;vector

f[maxn],rdio;

intn;

intper[maxn],dist[maxn];

bool

use[maxn];

int bfs(int s,int &ma)

for(int i=0; ii)

}return

loc;

}int

len;

intmadist[maxn];

bool jud(int dist, int &x, int &y)

d1=madist[y];

if(d1>dist) return

false

;

while(true

)

for(int i=x+1; ii)

return

true;}

intmain()

memset(use,

false,sizeof

(use));

intttt;

int st=bfs(1

,ttt);

memset(use,

false,sizeof

(use));

int ed=bfs(st,ttt);

memset(use,

false,sizeof

(use));

for(int i = ed; i!=-1; i=per[i])

for(int i=0; i

bfs(rdio[i],madist[i]);

len=rdio.size();

int l=0,r=n;

intx,y,anx,any;

while( l

else l=mid+1

; }

printf(

"%d %d %d\n

",r,rdio[anx],rdio[any]);

}return0;

}

view code

zoj 1101 二分搜尋

感覺時間複雜度還是太高了,一開始自己寫了個二分搜尋。比stl裡的要慢個幾毫秒。可能是資料量太少了,體現不出來。if 1 include include include include using namespace std define my max 1001 long dight my max i...

ZOJ1101 賭徒 二分查詢

這道題原本老師說是雜湊的練習題,結果發現雜湊的 量忒大,然後就用二分了。有n個賭徒,如果乙個賭徒的錢數是其中三個的和那麼這個賭徒是贏家,輸出最多錢的贏家。輸入乙個整數n 1 n 1000 表示有n個賭徒。接下去n行各自輸入乙個整數 x 536870912 輸出每組測試資料的結果。如果沒有勝者則輸出 ...

zoj 4029(數學 二分)

zoj 4029 思路 先預處理所有的ai i的字首和情況,因為i最多是30,p i ai,i在10 9內,所以可以確定i的邊界 然後對每個pi處理,將所有的求出ai每次求出pi對應的sum,再求出zi。參考文章 include include include includeusing namesp...