又是hack(29号再@管理)
查看原帖
又是hack(29号再@管理)
380730
xzCyanBrad楼主2023/1/22 12:58
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

正确答案:3636

这份代码输出 2525 还 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?
 **/
2023/1/22 12:58
加载中...