数组开2e4就RE, 下载数据本地能过, 把数组开2e5直接CE,??????
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e4 + 10;
template < typename T > inline void read(T &x) {
x = 0; T ff = 1, ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') ff = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
x *= ff;
}
int n, tot = 0, root, node, m[MAXN], lin[MAXN], siz[MAXN];
int ans1 = 0, ans2, dis[MAXN], vis[MAXN], hav[5], cnt[5], a[5] = {0, 2, 1};
struct edge {
int y, v, next;
}e[MAXN << 1];
inline void add(int xx, int yy, int vv) {
e[++tot].y = yy;
e[tot].v = vv;
e[tot].next = lin[xx];
lin[xx] = tot;
}
inline int Gcd(int x, int y) {
if (x % y == 0) return y;
return Gcd(y, x % y);
}
inline void getroot(int x, int fa) {
siz[x] = 1, m[x] = 0;
for (int i = lin[x]; i; i = e[i].next) {
int y = e[i].y;
if (y == fa || vis[y]) continue;
getroot(y, x);
siz[x] += siz[y];
m[x] = max(m[x], siz[y]);
}
m[x] = max(m[x], node - siz[x]);
if (m[x] < m[root]) root = x;
}
inline void getdis(int x, int fa) {
++cnt[dis[x] % 3];
for (int i = lin[x], y; i; i = e[i].next) {
if (vis[y = e[i].y] || y == fa) continue;
dis[y] = dis[x] + e[i].v;
getdis(y, x);
}
}
inline void calc(int x) {
hav[0] = 1;
for (int i = lin[x], y; i; i = e[i].next) {
if (vis[y = e[i].y]) continue;
cnt[0] = cnt[1] = cnt[2] = 0;
dis[y] = e[i].v;
getdis(y, x);
for (int j = 0; j <= 2; ++j) ans1 += cnt[j] * hav[a[j]];
for (int j = 0; j <= 2; ++j) hav[j] += cnt[j];
}
hav[0] = hav[1] = hav[2] = 0;
}
inline void dfz(int x) {
calc(x);
vis[x] = true;
for (int i = lin[x], y; i; i = e[i].next) {
if (vis[y = e[i].y]) continue;
root = 0;
m[0] = node = siz[y];
getroot(y, 0); getroot(root, 0);
dfz(root);
}
}
int main() {
read(n);
for (int i = 1; i < n; ++i) {
int x, y, v;
read(x), read(y), read(v);
v %= 3;
add(x, y, v);
add(y, x, v);
}
m[0] = node = n;
getroot(1, 0); getroot(root, 0);
dfz(root);
ans1 = ans1 * 2 + n;
ans2 = n * n;
int g = Gcd(ans1, ans2);
printf("%d/%d", ans1 / g, ans2 / g);
return 0;
}