社区讨论
求助Hack,必关
P6431[COCI 2008/2009 #1] KRTICA参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mil4qdwj
- 此快照首次捕获于
- 2025/11/30 10:57 3 个月前
- 此快照最后确认于
- 2025/12/02 16:10 3 个月前
我这个代码只做了第一个问,得了63分,还有一个点错了,实在不清楚哪里错了,对拍拍了两年半了,求救呀
CPP#include <cstdio>
#include <vector>
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MAXSZ = 1 << 20;
char ch, buf[MAXSZ], *p1, *p2;
#define ge() (p1 == p2 && (p2 = buf + fread(p1 = buf, 1, MAXSZ, stdin), p1 == p2) ? EOF : *p1++)
#define Debug() puts("I Love Furina forever!")
template <typename T_T>
inline void read(T_T &x) {
x = 0;
while (ch < '0' || '9' < ch) ch = ge();
while ('0' <= ch && ch <= '9') {
x = x * 10 + (ch ^ 48);
ch = ge();
}
}
template <typename T_T>
inline void write(T_T x) {
if (x > 9)
write(x / 10);
putchar(x % 10 | 48);
}
template <typename T_T>
inline T_T min(T_T a, T_T b) {return a < b ? a : b;}
template <typename T_T>
inline T_T max(T_T a, T_T b) {return a > b ? a : b;}
const int N = 5e5 + 5;
struct Tree {
int u;
ll w;
};
std::vector<Tree> tr[N];
int n, st, ed, dir[N], id, next[N];
ll maxn, Max[N], next_w[N], lhigh[N], rhigh[N], ldir[N], rdir[N];
bool vis[N];
void get_dir(int u, int fa, ll sum, int &node) {
if (maxn < sum) {
maxn = sum;
node = u;
}
for (auto edge : tr[u]) {
int v = edge.u, w = edge.w;
if (v == fa)
continue;
get_dir(v, u, sum + w, node);
}
}
void get_max_dist(int u, ll sum, int fa) {
maxn = max(maxn, sum);
for (auto edge : tr[u]) {
int v = edge.u, w = edge.w;
if (v == fa || vis[v])
continue;
get_max_dist(v, sum + w, u);
}
}
void find_past(int u, int fa) {
next[u] = fa;
for (auto edge : tr[u]) {
int v = edge.u, w = edge.w;
if (v == fa)
continue;
find_past(v, u);
next_w[v] = w;
}
}
int main() {
// freopen("Ryan.in", "r", stdin);
// freopen("Ryan.out", "w", stdout);
read(n);
for (int i = 1; i < n; i++) {
int u, v, w; read(u), read(v), w = 1;
tr[u].emplace_back((Tree){ v, w });
tr[v].emplace_back((Tree){ u, w });
}
maxn = 0, get_dir(1, -1, 0, st);
maxn = 0, get_dir(st, -1, 0, ed);
find_past(st, -1);
while (ed != -1) {
dir[++ id] = ed;
vis[ed] = true;
ed = next[ed];
}
for (int i = 1; i <= id; i++) {
maxn = 0;
get_max_dist(dir[i], 0, -1);
Max[dir[i]] = maxn;
// printf("%d%c", dir[i], i == id ? '\n' : ' ');
}
ll high = 0, sum = 0, mid = 1, tag = 0; lhigh[1] = 0; ldir[1] = 0;
for (int i = 2; i <= id; i++) {
sum += next_w[dir[i - 1]];
ll now_high = max(tag + next_w[dir[mid]], sum - tag - next_w[dir[mid]] + Max[dir[i]]);
high = max(high, sum - tag + Max[dir[i]]);
if (high >= now_high) {
high = now_high;
tag += next_w[dir[mid]];
mid ++;
}
lhigh[i] = high; ldir[i] = max(ldir[i - 1], sum + Max[dir[i]]);
}
ll Ssum = sum;
high = 0, tag = 0, sum = 0, mid = id; rhigh[id] = 0;
for (int i = id - 1; i >= 1; i--) {
sum += next_w[dir[i]];
ll now_high = max(tag + next_w[dir[mid - 1]], sum - tag - next_w[dir[mid - 1]] + Max[dir[i]]);
high = max(high, sum - tag + Max[dir[i]]);
if (high >= now_high) {
high = now_high;
tag += next_w[dir[mid - 1]];
mid --;
}
rhigh[i] = high; rdir[i] = max(rdir[i + 1], sum + Max[dir[i]]);
}
// for (int i = 1; i <= id; i++)
// printf("L:%lld %lld R:%lld %lld\n", lhigh[i], ldir[i], rhigh[i], rdir[i]);
ll ans = 2e18; sum = 0;
for (int i = 1; i <= id; i++) {
ans = min(ans, max(lhigh[i] + rhigh[i + 1] + next_w[dir[i]], max(ldir[i], rdir[i + 1])));
sum += next_w[dir[i]];
}
write(ans), putchar('\n');
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...