#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <cstring>
#include <vector>
using namespace std;
const int N = 2e4 + 5;
int n;
bool st[N];
int p[N][3], k[3];
struct Edge
{
int v, w;
Edge(int _v, int _w): v(_v), w(_w){}
};
vector<Edge> G[N];
int dis[N], col[N];
inline int read()
{
char ch = getchar();
int x = 0;
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x;
}
int get_wc(int u, int fa, int tot, int& wc)
{
if (st[u]) return 0;
int maxn = 0, sum = 0;
for (int i = 0; i < G[u].size(); i++)
{
int j = G[u][i].v;
if (j == fa) continue;
int k = get_wc(j, u, tot, wc);
maxn = max(maxn, k);
sum += k;
}
maxn = max(maxn, tot - sum);
if (maxn <= tot / 2) wc = u;
return sum;
}
int get_size(int u, int fa)
{
if (st[u]) return 0;
int res = 1;
for (int i = 0; i < G[u].size(); i++)
{
int j = G[u][i].v;
if (j == fa) continue;
res += get_size(j, u);
}
return res;
}
int wp[3];
void get_dist(int u, int fa, int& c, int color, int w)
{
if (st[u]) return;
dis[++c] = w;
p[color][w % 3]++;
k[w % 3]++;
col[c] = color;
for (int i = 0; i < G[u].size(); i++)
{
int j = G[u][i].v;
if (j == fa) continue;
get_dist(j, u, c, color, w + G[u][i].w);
}
}
int calc(int u)
{
if (st[u]) return 0;
k[0] = k[1] = k[2] = 0;
int res = 0;
get_wc(u, -1, get_size(u, -1), u);
st[u] = true;
int cur = 0;
for (int i = 0; i < G[u].size(); i++)
{
//wp[0] = wp[1] = wp[2] = 0;
get_dist(G[u][i].v, u, cur, i, G[u][i].w);
//bt[0].add(i + 1, wp[0], G[u].size());
//bt[1].add(i + 1, wp[1], G[u].size());
//bt[2].add(i + 1, wp[2], G[u].size());
}
for (int i = 1; i <= cur; i++)
{
res += (dis[i] % 3 == 0) << 1;
int cg = 3 - dis[i] % 3;
cg = cg % 3;
res += (k[cg] - p[col[i]][cg]);
}
for (int i = 0; i < G[u].size(); i++)
{
p[i][0] = p[i][1] = p[i][2] = 0;
}
for (int i = 0; i < G[u].size(); i++) res += calc(G[u][i].v);
return res;
}
signed main()
{
n = read();
for (int i = 1; i < n; i++)
{
int u = read(), v = read(), w = read();
G[u].push_back(Edge(v, w));
G[v].push_back(Edge(u, w));
}
int total = n * n, p = calc(1) + n, g = __gcd(total, p);
printf("%d/%d\n", p / g, total / g);
return 0;
}
这份代码在P2634上最后两个点T了,现在看来不是常数问题,应该是代码复杂度假了,但不知道问题在哪。能帮忙看看吗?