首先不難證明,最優解一定出現在直徑上,我們可以先跑兩次dfs求出來直徑
然後將直徑上的點的距離算一下,之後再算非直徑點的最大距離,求最大值即可
**
#includeusing namespace std;
const int maxn=3e5+5;
int n,s,tot,st,ed,max_dis;
int head[maxn],line[maxn],pre[maxn],dist[maxn],dis[maxn];
struct edge e[maxn<<1];
void add(int x,int y,int z)
void dfs(int u,int fa)
}void dfss(int u,int fa)
}int find(int x,int len)
} return x;
}int calc(int x,int len)
void ask(int x,int fa)
}int main()
dfs(1,0);
for(int i=1; i<=n; i++)
if(dist[i]>max_dis)
memset(dist,0,sizeof(dist));
max_dis=0;
dfss(st,0);
for(int i=1; i<=n; i++)
if(dist[i]>max_dis)
int now=ed;
while(now!=st)
} now=pre[now];
} now=ed;
int ans=1e9;
while(now!=st)
ans=min(ans,calc(st,s));
memset(dis,0,sizeof(dis));
now=ed;
while(now!=st)
for(int i=1; i<=n; i++) ans=max(ans,dis[i]);
printf("%d",ans);
return 0;
}
SDOI2013 直徑(樹的直徑)
小q最近學習了一些圖論知識。根據課本,有如下定義。樹 無迴路且連通的無向圖,每條邊都有正整數的權值來表示其長度。如果一棵樹有n個節點,可以證明其有且僅有n 1 條邊。路徑 一棵樹上,任意兩個節點之間最多有一條簡單路徑。我們用 dis a,b 表示點a和點b的路徑上各邊長度之和。稱dis a,b 為a...
SDOI2013 直徑(樹的直徑必經邊)
題目傳送 sol 先求出任一直徑同時把直徑拎出來,樹的非直徑部分全部掛在直徑上 如下 對於直徑上的每乙個點i,如果存在它到非直徑上點的最大距離 g i 等於它到直徑兩端點中較短的那一段 d i 則說明這一段也可以成為直徑中的一部分。而我們需要得到所有直徑的交,畫圖可以發現假設兩端 以中點為界 都存在...
P2491 消防 P1099 樹網的核
雙倍經驗,雙倍快樂。在乙個樹上選擇一段總長度不超過 s 的鏈使所有點到該鏈距離的最大值最小。輸出這個最小的值。define 以下 s 指鏈或鏈長。證明一下 s 一定處於直徑上。假設它不在直徑上,一定存在直徑的其中乙個端點到 s 的距離大於現在所處支鏈的最大距離。所以 s 不在直徑上一定不優。於是我們...