社区讨论

求助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 条回复,欢迎继续交流。

正在加载回复...