description
給出一棵樹,求出最小的k,使得,且在樹中存在路徑p,使得k>=s且k<=e。(k為路徑p上的邊的權值和)
input
第一行給出n,s,e。n代表樹的點數,s,e如題目描述。
下面n-1行給出這棵樹的相鄰兩個節點的邊及其權值w。
output
輸出共一行乙個整數,表示答案。若無解輸出-1。
sample input
5 10 40
2 4 80
2 3 57
1 2 16
2 5 49
sample output
16 【樣例解釋】
1到2的路徑即為答案。
對於20%的資料滿足n<=300
對於50%的資料滿足n<=3000
對於60%的資料滿足n<=10^5
對於以上資料,滿足|e-s|<=50
對於100%的資料滿足n<=10^5,|e-s|<=10^6
對於所有資料滿足1<=wi<=1000,|e|,|s|<=10^9
思路:比較裸的點分,不過這道題維護的是最小值,就沒有可減的性質了,所以去重(路徑兩端在同一子樹內)就要直接判斷。
#include
#include
#include
#include
#define ll long long
using
namespace
std;
const
int n = 100010;
int n, s, e, core, idc=0, sum;
int head[n], siz[n], mx[n], vis[n];
ll ans=2e17, dis[n];
struct edgeed[n<<2];
struct treea[n];
bool cmp(tree aa, tree bb)
void adde(int u, int v, ll w)
void getcore(int u, int f)
mx[u] = max(mx[u], sum-siz[u]);
if(mx[u] < mx[core]) core = u;
}void getdeep(int u, int f, int sroot)
a[++idc].tp = sroot;//屬於哪個子樹
a[idc].dis = dis[u];
}void count()
else
}}void solve(int u, int f)
}int main()
core = 0; mx[core] = 0x3fffffff; sum = n;
getcore(1, 0); solve(core, 0);
if( ans > e ) cout
<< -1
<< endl;//
else
cout
<< ans << endl;
return
0;}
JZOJ4715樹上路徑 點分治
這居然是聯賽題我一臉懵逼。根本沒往那方向上想。題目大意 讓你求樹上最短的路徑,但是路徑長度必須 l,r,n 10 5,r l 10 6,l,r 10 9 其實是我點分治沒怎麼打過,這其實是一道很一眼的點分治的題。我是懵比了。可以算是模板題吧,我是直接點分治莽一波,然後就過了,題解還說是二分,我比賽時...
JZOJ5055 樹上路徑
給定一棵 n 個節點的無根樹,每個點都有乙個非負整數的權值va li,定義一條路徑的價值為路徑上的點權和減去路徑的點權最大值。給定引數 p 請求出樹上有多少條價值是 p的倍數的路徑。注意 單點也算路徑。並且路徑 u v 和 v u 只算一次。1 n 105 1 p 107,0 va li 10 9 ...
JZOJ7月16日提高組T3 樹上路徑
題解現在有一棵n個點的無向樹,每個點的編號在1 n之間,求出每個點所在的最長路。輸入檔名為tree.in。第一行為乙個整數n。之後n 1行,每行三個整數u,v,w,分別表示一條邊連的兩個點和邊權。輸出檔案tree.out,共n行,分別表示經過每個點的最長路。41 2 3 1 3 4 1 4 277 ...