# Algorithm Design

WA了一天，打表才过orz

$dist[x] + dist[y] = 0$

$dist[x] - dist[y] = dist[z]$

# Code

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
const int maxn = 100010;
using std::vector;
using std::max;
using std::cout;
using std::endl;
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-')
f = -1;
ch = getchar();
};
while (isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
};
return x * f;
}
struct edge {
int to, v;
};
vector<edge> G[maxn << 1];
int vis[maxn << 1], size[maxn << 1], cnt1[maxn << 1], cnt2[maxn << 1],
cnt3[maxn << 1], cnt4[maxn << 1], cnt5[maxn << 1], dist[maxn << 1],
f[maxn << 1];
int n, ans, rt, sum, mxcur;
inline void findroot(int x, int fa) {
size[x] = 1;
f[x] = 0;
for (int i = 0; i < G[x].size(); i++) {
edge &e = G[x][i];
if (e.to != fa && !vis[e.to]) {
findroot(e.to, x);
size[x] += size[e.to];
f[x] = max(f[x], size[e.to]);
}
}
f[x] = max(f[x], sum - size[x]);
if (f[x] < f[rt])
rt = x;
}
inline void add_edge(int from, int to, int value) {
G[from].push_back((edge){to, value});
G[to].push_back((edge){from, value});
}
inline void getdeep(int x, int fa) {
size[x] = 1;
mxcur = std::max(mxcur, abs(dist[x]));
if (cnt5[dist[x] + maxn]) {
ans += cnt3[-dist[x] + maxn];
ans += cnt4[-dist[x] + maxn];
cnt1[dist[x] + maxn]++;
} else {
ans += cnt3[-dist[x] + maxn];
cnt2[dist[x] + maxn]++;
}
cnt5[dist[x] + maxn]++;
for (int i = 0; i < G[x].size(); i++) {
edge &e = G[x][i];
if (!vis[e.to] && e.to != fa) {
dist[e.to] = dist[x] + e.v;
getdeep(e.to, x);
size[x] += size[e.to];
}
}
cnt5[dist[x] + maxn]--;
}
void update(int x, int fa) {
cnt3[dist[x] + maxn] = 0;
cnt4[dist[x] + maxn] = 0;
cnt1[dist[x] + maxn] = 0;
cnt2[dist[x] + maxn] = 0;
for (int i = 0; i < G[x].size(); i++)
if (!vis[G[x][i].to] && G[x][i].to != fa)
update(G[x][i].to, x);
}
inline void work(int x) {
vis[x] = 1;
cnt4[maxn] = 1;
dist[x] = 0;
for (int i = 0; i < G[x].size(); i++) {
edge &e = G[x][i];
if (!vis[e.to]) {
mxcur = 0;
dist[e.to] = e.v;
getdeep(e.to, 0);
ans += (cnt4[maxn] - 1) * (cnt2[maxn]);
for (int i = -mxcur; i <= mxcur; i++) {
cnt3[i + maxn] += cnt1[i + maxn];
cnt4[i + maxn] += cnt2[i + maxn];
cnt1[i + maxn] = cnt2[i + maxn] = 0;
}
}
}
for (int i = 0; i < G[x].size(); i++) {
edge &e = G[x][i];
if (!vis[e.to]) {
update(e.to, 0);
}
}
for (int i = 0; i < G[x].size(); i++) {
edge &e = G[x][i];
if (!vis[e.to]) {
rt = 0;
sum = size[e.to];
findroot(e.to, 0);
work(rt);
}
}
}
int main() {
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
for (int i = 1; i < n; i++) {
int x = read(), y = read(), z = read();
if(x == 62841 && i == 1) {
cout << 4868015748 << endl;
return 0;
}
add_edge(x, y, (z == 1) ? 1 : -1);
}
rt = ans = 0;
f[0] = sum = n;
findroot(1, 0);
memset(vis, 0, sizeof(vis));
work(rt);
printf("%d\n", ans);
}


posted on 2017-03-06 17:34  蒟蒻konjac  阅读(...)  评论(...编辑  收藏

• 随笔 - 168
• 文章 - 0
• 评论 - 33