poj2831 樹的直徑 bfs dfs

2021-08-17 18:00:20 字數 2014 閱讀 3963

這裡給出樹的直徑的證明:

主要是利用了反證法:

假設 s-t這條路徑為樹的直徑,或者稱為樹上的最長路

現有結論,從任意一點u出發搜到的最遠的點一定是s、t中的一點,然後再從這個最遠點開始搜,就可以搜到另乙個最長路的端點,即用兩遍廣搜就可以找出樹的最長路

證明:1.設u為s-t路徑上的一點,結論顯然成立,否則設搜到的最遠點為t則   dis(u,t) >dis(u,s)     且  dis(u,t)>dis(u,t)   則最長路不是s-t了,與假設矛盾

2.設u不為s-t路徑上的點

首先明確,假如u走到了s-t路徑上的一點,那麼接下來的路徑肯定都在s-t上了,而且終點為s或t,在1中已經證明過了

所以現在又有兩種情況了:

1:u走到了s-t路徑上的某點,假設為x,最後肯定走到某個端點,假設是t ,則路徑總長度為dis(u,x)+dis(x,t)

2:u走到最遠點的路徑u-t與s-t無交點,則dis(u-t) >dis(u,x)+dis(x,t);顯然,如果這個式子成立,

則dis(u,t)+dis(s,x)+dis(u,x)>dis(s,x)+dis(x,t)=dis(s,t)最長路不是s-t矛盾 (見下圖)

求樹的直徑用2次bfs和2次dfs都可以。

用兩次bfs**:

#includeusing namespace std;

#define maxn 10010 //最多有10000個村莊,最多有幾條邊?最多有n-1條邊

struct node

}edge[maxn];

int head[maxn],dis[maxn],vis[maxn];

int num=1;

int us,maxm;

void addedge(int from ,int to,int value)

void bfs(int u)找到那條離1最遠的點。就要把1到每個點的距離算出來

maxm=0;

memset(vis,0,sizeof(vis));

memset(dis,0,sizeof(dis));

//int first;

queueque;//放進去的是點!!!

que.push(u);

vis[u]=1;

while(!que.empty())

que.push(v);

vis[v]=1;

}} }

}int main()

bfs(1);

bfs(us);

cout彈出來樹點的編號,根據head來確定首先訪問從當前點開始的那條邊,i就指向了下一條,如果i是0,表示next=0,也就是沒有後邊的邊了。當然這個也是需要vis陣列的,如果沒有就會重複放,因為邊是雙向的。而且在算距離的時候,應該是u的距離加上當前邊的長度(一開始我想的是原來的長度加上邊的長度?什麼鬼啊。。。。)在比較的過程中記錄最大值即可。

下邊是dfs:

#include#include#include#includeusing namespace std;

#define maxn 10010 //最多有10000個村莊,最多有幾條邊?最多有n-1條邊

struct node

}edge[maxn];

int head[maxn],dis[maxn],vis[maxn];

int num=1;

int us=0,maxm=0;

void addedge(int from ,int to,int value)

void dfs(int u)

dfs(v);

} }

}int main()

maxm=0;

memset(vis,0,sizeof(vis));

memset(dis,0,sizeof(dis));

dfs(1);

maxm=0;

memset(vis,0,sizeof(vis));

memset(dis,0,sizeof(dis));

dfs(us);

cout<

poj 2831 次小生成樹模板

次小生成樹 題意 給你一些路徑,現在將一部分路徑權值減少後問是否可以替代最小生成樹裡面的邊。解 次小生成樹,即將這條邊連上,構成乙個環 求出任意兩點路徑之間的除了這條邊的最大值,比較這個最大值 這條邊,說明可以替換。prime演算法次小生成樹模板 include include define n 1...

poj 1985 樹的直徑

題意 求樹的直徑。樹的直徑即樹上距離最遠的兩個點之間的距離 思路 以任意點開始深搜,得到距離其最遠的點 再以求得的點開始深搜,再次搜得的最遠距離即為樹的直徑 include include define n 100005 struct edgee n 2 int first n flag n top...

poj4607 樹的直徑)

題目 park visit 題意 乙個人去公園,想走k個景點,問最短的距離。思路 求出樹的直徑 最長的鏈 最長路徑 從任意點a,找到離a最遠點b。再找到離b最遠點c,bc就是最長路徑。如果k include include include include include include includ...