k的值很大答案应该用long long。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
#define maxn 111111
#define maxm 211111
#define INF 11111111
#define size Size
struct node {
int from, to, next;
long long w;
}edge[maxm];
int n, m, k, cnt, root;
long long ans;
int head[maxn];
bool vis[maxn];
int size[maxn], num[maxn]; //以i为根的子树的节点 i的子树中最多的节点
long long d[maxn], Min;
void add_edge (int from, int to, int w) {
edge[cnt].from = from, edge[cnt].to = to, edge[cnt].w = w, edge[cnt].next = head[from],
head[from] = cnt++;
}
void dfs_size (int u, int fa) {
size[u] = 1;
num[u] = 0;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (v == fa || vis[v])
continue;
dfs_size (v, u);
size[u] += size[v];
if (size[v] > num[u]) {
num[u] = size[v];
}
}
}
void find_root (int u, int fa, int pre) { //找到重心
long long cur = 0;
cur = max (num[u], size[pre]-size[u]);
if (cur < Min) {
Min = cur;
root = u;
}
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (v == fa || vis[v])
continue;
find_root (v, u, pre);
}
}
int tmp[maxn], tot;
void get_dis (int u, int fa, int dis) { //得到每个点到当前根的距离
tmp[tot++] = dis;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (vis[v] || v == fa)
continue;
d[v] = dis+edge[i].w;
get_dis (v, u, d[v]);
}
}
int solve (int u, int d) {
long long ans = 0;
tot = 0;
get_dis (u, 0, d);
sort (tmp, tmp+tot);
int r = tot-1, l = 0;
while (r>l) {
for (; tmp[r]+tmp[l] > k && r > l; r--) {}
ans += r-l;
l++;
}
return ans;
}
void dfs (int u) {
Min = INF;
dfs_size (u, 0);
find_root (u, 0, u);
vis[root] = 1;
ans += solve (root, 0);
for (int i = head[root]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (vis[v])
continue;
ans -= solve (v, edge[i].w);
dfs (v);
}
}
int main () {
//freopen ("in", "r", stdin);
while (scanf ("%d%d", &n, &m) == 2) {
cnt = ans = 0;
int u, v, w;
char op[10];
memset (head, -1, sizeof head);
for (int i = 1; i < n; i++) {
scanf ("%d%d%d%s", &u, &v, &w, &op);
add_edge (u, v, w);
add_edge (v, u, w);
}
scanf ("%d", &k);
memset (vis, 0, sizeof vis);
dfs (1);
printf ("%lld\n", ans);
}
return 0;
}