初學點分治

2021-08-28 03:27:47 字數 2246 閱讀 5475

前言

在我的心目中,點分治是乙個非常難的演算法,但在解決一些樹上問題時也非常實用。為此,我特地去學了學點分治這個高深的演算法。

什麼是樹的重心

在學習點分治之前,我們先來解決乙個問題:什麼是樹的重心

在一棵樹上找到乙個點,使得刪去這個點後得到的子樹中節點數最大的子樹最小,那麼這個點就叫做樹的重心

那麼樹的重心具體有什麼作用呢?

這在之後會提到。

下面,讓我們先來看一看點分治的核心思想。

核心思想

以一道模板題為例:【洛谷3806】【模板】點分治1。

第一步,我們要找到乙個節點rt

r

t,將無根樹轉化為有根樹

不難發現,在這棵樹上的路徑只有兩種:

經過根節點的路徑。

不經過根節點的路徑,則這條路徑必定位於當前根節點的某個子樹中。

對於第一種情況,我們可以在確定根節點的情況下在o(

n)o (n

)的時間複雜度下處理掉。

而對於第二種情況,我們就需要繼續處理這條路徑所在的子樹,並重複以上步驟,求出答案

這個時候就不難想到分治了。

我們可以將當前處理到的子樹分成若干個小子樹,分別求出答案。

這時我們再考慮,rt

r

t取什麼節點才會使複雜度最優?

我們可以取樹的重心,使得剩下的子樹大小盡量平均,時間複雜度也會大大優化,大致為o(

nlog

2n) o(n

log2

n)

。**

#include

#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define ll long long

#define swap(x,y) (x^=y,y^=x,x^=y)

#define abs(x) ((x)<0?-(x):(x))

#define fsize 100000

#define tc() (finnow==finend&&(finend=(finnow=fin)+fread(fin,1,fsize,stdin),finnow==finend)?eof:*finnow++)

#define n 10000

#define m 100

#define add(x,y,z) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].val=z)

char fin[fsize],*finnow=fin,*finend=fin;

using namespace std;

const char ans[2][4]=;

int n,m,rt,top,ee=0,lnk[n+5],size[n+5],maxsize[n+5],used[n+5],dis[n+5],stack[n+5],exist[10000005];

struct edge

e[2*n+5];

struct query

q[m+5];

inline void read(int &x)

inline void getrt(int

x,int lst,int sum)//確定根節點,即找到樹的重心

if((maxsize[x]=max(maxsize[x],sum-size[x]))x;//如果當前節點最大子樹節點數比原本找到的重心的最大子樹節點數小,就更新重心

}inline void dfs(int

x,int lst)//搜尋處理出答案

inline void f5(int

x,int t)//更新答案

inline void getans(int

x)//處理以x為根節點的子樹

for(i=lnk[x];i;i=e[i].nxt)//列舉每乙個與當前節點相鄰的節點

if(!used[e[i].to]) getrt(e[i].to,rt=0,size[e[i].to]),getans(rt);//如果列舉到的節點沒有被作為過根節點,就對這個子樹進行處理

}int main()

初學點分治

在我的心目中,點分治是乙個非常難的演算法,但在解決一些樹上問題時也非常實用。為此,我特地去學了學點分治這個高深的演算法。在學習點分治之前,我們先來解決乙個問題 什麼是樹的重心?在一棵樹上找到乙個點,使得刪去這個點後得到的子樹中節點數最大的子樹最小,那麼這個點就叫做樹的重心。那麼樹的重心具體有什麼作用...

pyqt初學 點選按鈕開啟新介面以及退出視窗

在qt designer中設計好兩個視窗之後,在pycharm進行編譯,生成兩個py檔案。給主視窗的py檔案匯入 from 你的副視窗檔名 import 你的副視窗物件名 在retranslateui函式,你要按的按鈕下新增 self.pushbutton.clicked.connect self....

每天學點Linux

1.程序檢視刪除 ps 檢視當前正在執行的程序資訊,aux顯示所有狀態。可以確定哪些程序正在執行 執行狀態 程序是否結束 程序有沒有僵死 程序占用資源情況。eg ps aux grep tomcat kill終止程序,9強迫程序立刻終止 eg kill 9 pid killall 9 程序名 2.統...