題目描述
奶牛們想建立一個新的城市。它們想建立一條長度爲 Len 的主線大街,然後建立 K 條小街,每條小街的盡頭有一間房子(小街的其它位置沒有房子)。每條小街在主線大街的P_i 處分支, 小街的長度用L_i表示。FJ想知道最遠的兩個房子之間的距離是多少。
輸入
第 1 行: 兩個整數 Len 和K,意義如題目描述。
第2…K+1行: 每行兩個整數P_i和L_i,對應着一條小街的信息。
輸出
輸出共一行一個整數,即最遠的兩個房子之間的距離。
樣例輸入
【輸入樣例1】
5 4
5 6
2 2
0 3
2 7
【輸入樣例2】
5 4
2 4
2 2
2 10
2 7
樣例輸出
【輸出樣例1】
16
【輸出樣例2】
17
數據範圍限制
對於30%的數據: 1≤Len≤500;2≤K≤100;1≤L_i≤1,000;
對於60%的數據: 1≤Len≤5,000;2≤K≤5,000;1≤L_i≤1,000,000;
對於100%的數據:1≤Len≤100,000,000;2≤K≤500,000;0≤P_i≤Len;1≤L_i≤100,000,000;
提示
【樣例1解釋】主線大街長度是5,有4條小街,分別位於距離主線大街 0、2、 2、 5 處。這4條小街的長度分別是3、 2、 7、 6。注意:主線大街的同一個地點可以有多條小街;房子 #1 和房子 #4 的距離最遠,最遠距離是16。
題解:
樹的直徑。
鋪墊:
- 樹的直徑指數上相距最長的兩個點。
- 尋找方法: 先從某個結點找距離最長的結點v,這是直徑的一段,再以這個點找距離最長的結點u,那麼這棵樹的直徑是uv。
思路:
我們把第一個小街設爲根節點,就可以出現如右圖的的的一棵樹。
所以我們找樹的直徑時就可以用for來搞定。
for(int i=2;i<=k;i++){
int o=p[i]-p[1]+l[i]+l[1];
if(o>ans){
ans=o;
d=i;
}
}
ans=0;
for(int i=1;i<=k;i++){
if(i!=d){
int o=abs(p[i]-p[d])+l[i]+l[d];
if(o>ans){
ans=o;
v=i;
}
}
}
printf("%d",ans);