bob 的城市裡有 nn 個郵遞站,由於經濟考慮,這些郵遞站被 n - 1n−1 條帶權無向邊相連。即:這 nn 個郵遞站構成了一棵樹。
bob 正在應聘乙個快遞員的工作,他需要送 mm 個商品,第 ii 個商品需要從 uu 送到 vv。由於 bob 不能帶著商品走太長的路,所以對於一次送貨,他需要先從快遞中心到 uu,再從 uu 回到快遞中心,再從快遞中心到 vv,最後從 vv返回快遞中心。換句話說,如果設快遞中心是 cc 號點,那麼他的路徑是 c \rightarrow u \rightarrow c \rightarrow v \rightarrow cc→u→c→v→c。
現在 bob 希望確定乙個點作為快遞中心,使得他送貨所需的最長距離最小。顯然,這個最長距離是個偶數,你只需要輸出最長距離除以 22 的結果即可。
輸入格式:
第一行輸入兩個數 n, mn,m,意義如上。
接下來n-1n−1行,每行三個數 u_i, v_i, w_iui,vi,wi,表示一條連線 u_i, v_iui,vi,長度為 w_iwi的邊。
接下來 mm 行,每行兩個整數 u_i, v_iui,vi,表示商品的起止位置。
輸出格式:
一行乙個整數,表示答案。
輸入樣例#1:
3 11 2 1
2 3 1
1 3
輸出樣例#1:
2
對於 25\%25% 的資料,滿足 1 \leq n, m \leq 10001≤n,m≤1000。
對於 100\%100% 的資料,滿足 1 \leq n, m \leq 10^5, 1 \leq w_i \leq 10001≤n,m≤105,1≤wi≤1000。
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;
6const
int n=100010;7
int n,m,cnt,root,sum,ans=10000*n,u[n],v[n],head[n],size[n],mx[n],bz[n],dis[n],q[n];
8bool
vis[n];
9struct edge e[n*2
];10
void insert(int x,int y,int
v)11
15void getdis(int x,int fa,int
y)16
20void getroot(int x,int
fa)21
28 mx[x]=max(mx[x],sum-mx[x]);
29if (mx[x]x;30}
31void solve(int
x)32
34 vis[x]=true,dis[x]=0;35
for (int i=head[x];i;i=e[i].from) dis[e[i].to]=e[i].v,getdis(e[i].to,x,e[i].to);
36int mx=0,len=0,ls=0;37
for (int i=1;i<=m;i++) if (dis[u[i]]+dis[v[i]]>mx) q[len=1]=i,mx=dis[u[i]]+dis[v[i]]; else
if (dis[u[i]]+dis[v[i]]==mx) q[++len]=i;
38 ans=min(ans,mx);
39for (int i=1;i<=len;i++)
4042
if (!ls) ls=bz[u[q[i]]];
43if (bz[u[q[i]]]!=ls) 44}
45 root=0,sum=size[ls],getroot(ls,0
),solve(root);46}
47int
main()
48
CSP S 2019 樹的重心 重心
題意 給定一棵樹 測試資料中樹的結點數中告知 求斷掉每條邊兩棵子樹所有重心的編號和之和。題解 重心 樹狀陣列 先隨便求個重心出來,記做 k 子樹大小記為 sz 子結點子樹大小的最大值記為 mx 考慮乙個結點 u not k 首先,割掉一條邊使得 u 成為所在連通塊的重心,這條邊一定不在 u 子樹內。...
求樹的重心
題目 題意 給定一棵樹,求樹的重心的編號以及重心刪除後得到的最大子樹的節點個數size,如果size相同就選取編號最小的.分析 首先要知道什麼是樹的重心,樹的重心定義為 找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵 樹的重心,刪去重 心後,生成的多棵樹盡可能平衡.實際上樹的重心...
專題 樹的重心
定義1 找到乙個點,刪除它得到的森林中最大的子樹節點數最少,那麼這個點就是這棵樹的重心。定義2 刪除重心後得到的所有子樹,其頂點樹必然不超過n 2 性質1 樹中所有點到某個點的距離和中,到重心的距離和是最小的 如果有兩個重心,那麼他們的距離和一樣。性質2 把兩個樹通過一條邊相連得到乙個新的樹,那麼新...