大臣的旅費 藍橋杯

2021-06-29 14:18:31 字數 1610 閱讀 7193

給你一顆樹,讓你求出樹上最遠的倆個點的距離

先以第乙個頂點為根,進行一次dfs,找出從第乙個點出發的最長的乙個直徑,然後再以直徑的另外乙個端點a,為根進行一次dfs,又可以找出另外乙個端點b,可以證明(a,b)即為樹的直徑(樹上任意倆點最遠的距離)

下面是對這種證法的詳細證明:(不是我證的。。。。。。)

為了闡述清楚證明,首先作如下嚴格定義:

1。我們用a~b表示樹中任意兩個結點a,b之間的唯一路徑,a~b之間可以有0個或多個結點

;用x \in a~b表示結點x處於路徑a,b上,即存在形如a~x~b的路徑(這裡x可以和a或b

重合);用符號a-b表示a,b直接相鄰。

定理5: 設r是樹t的根,u是距離r最遠的結點,v是距離u最遠的結點。則樹的直徑就是d(u

, v)。

證明:設a, b是除了u,v以外的另外兩個葉節點。設x = f(f(a, b), u)。即x是a,b,u三個

節點的最近公共祖先。

根據引理4,一定有 x \in u~a 或 x \in u~b。不妨設x \in u~b 成立。

於是就有u~x~b這條路徑,即

d(u,b) = d(u,x)+d(x,b) ......(1) 於是

d(r,u) >= d(r,a)                    // 因為u是距離r最遠的點

==> d(r,x) + d(x,u) >= d(r,x) + d(x,a)  // 因為根據公共祖先的定義,x \in r~u 

且 x \in r~a

==> d(u,x) >= d(x,a) ........(2) 於是

d(u,v) >= d(u,b)          // 因為v是距離u最遠的點

= d(u,x)+ d(x,b) // 根據(1)式

>= d(x,a) + d(x,b) // 根據(2)式  

>= d(a,b)          // 根據引理2

所以對於除了u,v外任意的葉節點a,b,總有d(u, v)>= d(a,b)。

如果a,b中有乙個是u,v之一,顯然也有d(u, v)>=d(a,b)。

再根據引理1和樹的半徑的定義,可知d(u,v)就是t的直徑。

#include#include#include#include#includeusing namespace std;

#define maxn 10100

struct edge

};int n;

int dist[maxn],max_len,end;

vector>g;

void dfs(int u,int father,int len)

}int main()

memset(dist,0,sizeof(dist));

max_len=0;

dfs(1,-1,0);

dfs(end,-1,0);

int ans=0;

for(int i=1;i<=n;i++)

int tt=0;

for(int i=1;i<=ans;i++)

tt+=(10+i);

printf("%d\n",tt);

}return 0;

}

藍橋杯 大臣旅費

一開始就是覺得用dfs想不通為什麼網上是說兩遍dfs bfs找出當前最大邊 樹的最大直徑 後來發現純dfs時間代價太大了o n 附上純dfs include include int n,visited 1000 point 1000 int dist 1000 1000 void end if su...

藍橋杯 大臣的旅費

問題描述 很久以前,t王國空前繁榮。為了更好地管理國家,王國修建了大量的快速路,用於連線首都和王國內的各大城市。為節省經費,t國的大臣們經過思考,制定了一套優秀的修建方案,使得任何乙個大城市都能從首都直接或者通過其他大城市間接到達。同時,如果不重複經過大城市,從首都到達每個大城市的方案都是唯一的。j...

藍橋杯 大臣的旅費

問題描述 很久以前,t王國空前繁榮。為了更好地管理國家,王國修建了大量的快速路,用於連線首都和王國內的各大城市。為節省經費,t國的大臣們經過思考,制定了一套優秀的修建方案,使得任何乙個大城市都能從首都直接或者通過其他大城市間接到達。同時,如果不重複經過大城市,從首都到達每個大城市的方案都是唯一的。j...