19 90
2 9 15
4 7 0
2 15 17
5 4 11
19 11 2
2 3 2
1 2 18
18 10 13
13 7 17
6 2 14
13 16 8
9 10 11
8 3 16
9 14 19
17 11 3
4 1 16
8 11 15
9 12 4
正确答案:36。
这份代码输出 25 还 A 了(拍了几百组)
// Author: XZC(L_Wave)
// Language: Cpp/G++14
// Problem: P1099 [NOIP2007 鎻愰珮缁刔 鏍戠綉鐨勬牳
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1099
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// Create Time: 2023-01-21 12:32:13
// Solution 3
// Powered by CP Editor (https://cpeditor.org)
//#pragma GCC optimize("Ofast", "inline")
#include<bits/stdc++.h>
namespace std
{
template<typename T1,typename T2,typename T3>struct triplet{
T1 first;T2 second;T3 third;
friend bool operator ==(triplet x,triplet y){return x.first==y.first&&x.second==y.second&&x.third==y.third;}
friend bool operator !=(triplet x,triplet y){return x.first!=y.first||x.second!=y.second||x.third!=y.third;}
friend bool operator <(triplet x,triplet y){return x.first==y.first?x.second==y.second?x.third<y.third:x.second<y.second:x.first<y.first;}
friend bool operator >(triplet x,triplet y){return x.first==y.first?x.second==y.second?x.third>y.third:x.second>y.second:x.first>y.first;}
friend bool operator <=(triplet x,triplet y){return x.first==y.first?x.second==y.second?x.third<=y.third:x.second<y.second:x.first<y.first;}
friend bool operator >=(triplet x,triplet y){return x.first==y.first?x.second==y.second?x.third>=y.third:x.second>y.second:x.first>y.first;}
friend triplet operator +(triplet x,triplet y){return (triplet){x.first+y.first,x.second+y.second,x.third+y.third};}
friend triplet operator -(triplet x,triplet y){return (triplet){x.first-y.first,x.second-y.second,x.third-y.third};}
triplet& operator +=(triplet x){return (*this)=(*this)+x;}
triplet& operator -=(triplet x){return (*this)=(*this)-x;}
};
template<typename T1,typename T2,typename T3>triplet<T1,T2,T3> make_triplet(T1 x,T2 y,T3 z){
triplet<T1,T2,T3> res;
res.first=x;res.second=y;res.third=z;return res;
}
}
#define Rep(i, n) for(int i=0; i< (int)(n); i++)
#define Rpp(i, n) for(int i=1; i<=(int)(n); i++)
#define Dpp(i, n) for(int i=(int)n; i; i--)
#define Frr(i, s, e) for(int i=(int)(s); i<=(int)(e); i++)
#define Tc int T; cin >> T; while(T--)
#define Eps 1e-7
#define Pinf 0x3f3f3f3f3f3f3f3fLL
#define Ninf (long long)0xcfcfcfcfcfcfcfcfLL
#define Mem0(Cont) memset(Cont, 0, sizeof(Cont))
#define MemP(Cont) memset(Cont, 0x3f, sizeof(Cont))
#define MemN(Cont) memset(Cont, 0xcf, sizeof(Cont))
#define endl '\n'
//#define int long long
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define yes cout << "yes\n"
#define no cout << "no\n"
//#define Files
using namespace std;
template <typename T> inline void Print(T x, char ed = '\n') { cout << x << ed; }
template <typename T> inline void Exit(T x, int cd = 0) { cout << x << endl; exit(cd); }
template <typename T> inline bool CheckMax(T& x, T y) { if(x < y) { x = y; return 1; } else return 0; }
template <typename T> inline bool CheckMin(T& x, T y) { if(y < x) { x = y; return 1; } else return 0; }
inline void Print_if(bool sth, string s1 = "Yes", string s2 = "No") { if(sth) cout << s1 << endl; else cout << s2 << endl; }
int n, s, vis[500010], head[500010], far[500010], dd[500010], dia[500010], top, kk;
bool ban[500010];
struct Edge {
int v, w, nxt;
} E[1000010];
mt19937 mmtt;
void addEdge(int u, int v, int w) {
E[++kk] = {v, w, head[u]}; head[u] = kk;
E[++kk] = {u, w, head[v]}; head[v] = kk;
}
int Bfs(int u) {
queue < pair <int, int> > Q;
Q.push({u, 0});
int v = 0, d = -1, idx = mmtt();
while(Q.size()) {
pair <int, int> P;
P = Q.front(); Q.pop();
u = P.first;
vis[u] = idx;
int w = P.second;
if(CheckMax(d, w)) v = u;
for(int II = head[u]; II; II = E[II].nxt) {
int ev = E[II].v, ew = E[II].w;
if(vis[ev] != idx) Q.push({ev, w+ew});
}
}
return v;
}
bool Bfs2(int u, int k) {
queue < pair <int, int> > Q;
Q.push({u, 0});
int idx = mmtt();
while(Q.size()) {
pair <int, int> P;
P = Q.front(); Q.pop();
u = P.first;
vis[u] = idx;
int w = P.second;
if(u == k) return w <= s;
for(int II = head[u]; II; II = E[II].nxt) {
int ev = E[II].v, ew = E[II].w;
if(vis[ev] != idx) Q.push({ev, w+ew});
}
}
return 0;
}
bool Dfs(int u, int p, int tg) {
dia[top++] = u;
if(u == tg) return 1;
for(int II = head[u]; II; II = E[II].nxt) {
int v = E[II].v;
if(v == p) continue;
bool flg = Dfs(v, u, tg);
if(flg) return 1;
}
--top;
return 0;
}
int Dfs_ban(int u, int ban_id, int dep = 0) {
// cout << ban[u] << ' ' << ban_id << endl;
ban[u] = ban_id;
// cout << u << ' ' << ban_id << ' ' << dep << ' ' << ban[u] << endl << flush;
int mx = dep;
for(int II = head[u]; II; II = E[II].nxt) {
int v = E[II].v, w = E[II].w;
if(ban[v] != ban_id) {
CheckMax(mx, Dfs_ban(v, ban_id, dep+w));
}
}
return mx;
}
void readGraph() {
cin >> n >> s;
Rpp(i, n-1) {
int u, v, w;
cin >> u >> v >> w;
addEdge(u, v, w);
}
}
void diamDis() {
int ban_id = 1;
Rep(k, top) {
int v = dia[k];
ban[v] = ban_id;
}
Rep(k, top) {
int v = dia[k];
far[v] = Dfs_ban(v, ban_id);
// cout << v << ' ' << far[v] << endl;
}
}
bool check(int x) {
int sum = 0, l = top-1, r = 0;
Rpp(i, top-1) {
sum += dd[i-1];
if(sum > x) {
l = i-1;
break;
}
}
// if(l == -1) return 0;
sum = 0;
Dpp(I, top-1) {
int i = I-1;
sum += dd[i];
// cout << i << ' ' << sum << endl;
if(sum > x) {
r = i+1;
break;
}
}
if(l >= r) return 1;
// if(r == -1) return 0;
sum = 0;
int mx = 0;
Frr(i, l, r-1)
sum += dd[i];
Frr(i, l, r)
CheckMax(mx, far[i]);
// cout << dia[l] << ' ' << dia[r] << endl;
return sum <= s && mx <= x;
}
inline void solve() {
readGraph();
int L = Bfs(1), R = Bfs(L);
if(L > R) swap(L, R);
Dfs(L, 0, R);
diamDis();
// for(const auto& v : dia) cout << far[v] << endl;
Rep(i, top-1) {
for(int II = head[dia[i]]; II; II = E[II].nxt) {
int v = E[II].v, w = E[II].w;
if(v == dia[i+1]) dd[i] = w;
}
}
// cout << check(0) << endl; return ;
int lo = 0, hi = (1<<30)-1+(1<<30), mi, res = -1;
while(lo <= hi) {
mi = (0ll + lo + hi) >> 1;
// cout << mi << endl << flush;
if(check(mi)) {
hi = mi-1;
res = mi;
} else
lo = mi+1;
}
cout << res << endl;
}
signed main()
{
#ifdef Files
freopen(".in", "r", stdin);
freopen(".out", "w",stdout);
#endif
ios_base :: sync_with_stdio(0), cin.tie(0), cout.tie(0);
solve();
return 0;
}
/*
* things to check
* 1. int overflow or long long memory need
* 2. recursion/array/binary search/dp/loop bounds
* 3. precision
* 4. special cases(n=1,bounds)
* 5. delete debug statements
* 6. initialize(especially multi-tests)
* 7. = or == , n or m ,++ or -- , i or j , > or >= , < or <=
* 8. keep it simple and stupid
* 9. do not delete, use // instead
* 10. operator priority
* 11. is there anything extra to output?
* 12. THINK TWICE CODE ONCE, THINK ONCE DEBUG FOREVER
* 13. submit ONCE, AC once. submit twice, WA forever
* 14. calm down and you'll get good rank
* 15. even a bit wrong scores zero
* 16. ...
**/
/*
* something to think about
* 1. greedy? dp? searching? dp with matrix/ segment tree? binary search? ...?
* 2. If it is difficult, why not the opposite?
**/