zzozz @ 2017-10-11 07:45:53
思路就是求lca搜索一个子树时在子树上相关的点打标记 计算桶的变化值,回溯是把以当前点为lca的相关点的桶值删掉,然后第13个点WA了
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
const int maxn = 300010;
const int maxm = 300010;
using namespace std;
vector <int> del[maxn];
bool vis[maxn];
int n, m, ecnt, qecnt;
int head[maxn], qhead[maxn], ans[maxn], cnt[maxn * 2], deep[maxn], fa[maxn], t[maxn];
struct Edge{
int to, nex, fro, lca;
}es[maxn * 2], qes[maxm * 2];
int read(){
int x = 0, f = 1;
char ch;
do {
ch = getchar();
if (ch == '-') f = -1;
}while(ch < '0' || ch > '9');
do {
x = x * 10 + ch - 48;
ch = getchar();
}while(ch >= '0' && ch <= '9');
return x * f;
}
void add(int u,int v){
es[ecnt].to = v;
es[ecnt].nex = head[u];
head[u] = ecnt ++;
}
void qadd(int u,int v){
qes[qecnt].to = v;
qes[qecnt].fro = u;
qes[qecnt].nex = qhead[u];
qhead[u] = qecnt ++;
}
void Dfs(int u,int fa){
for (int i = head[u];i != -1;i = es[i].nex){
int v = es[i].to;
if (v == fa) continue;
deep[v] = deep[u] + 1;
Dfs(v, u);
}
}
int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
void tarjan(int u){
vis[u] = true;
fa[u] = u;
for (int i = head[u];i != -1;i = es[i].nex){
int v = es[i].to;
if (vis[v]) continue;
tarjan(v);
fa[v] = u;
}
for (int i = qhead[u];i != -1;i = qes[i].nex){
int v = qes[i].to;
if (vis[v]){
qes[i].lca = find(v);
qes[i ^ 1].lca = qes[i].lca;
}
}
}
void dfs(int u,int fa,int cnt1,int cnt2){
for (int i = qhead[u];i != -1;i = qes[i].nex)
if (i & 1){
int v = qes[i].to;
int lca = qes[i].lca;
int dis = deep[v] + deep[u] - 2 * deep[lca];
cnt[deep[u] - dis + maxn] ++;
}
else cnt[deep[u]] ++;
for (int i = head[u];i != -1;i = es[i].nex){
int v = es[i].to;
if (v == fa) continue;
dfs(v, u, cnt[deep[v] + t[v]], cnt[deep[v] - t[v] + maxn]);
}
ans[u] = cnt[deep[u] + t[u]] + cnt[deep[u] - t[u] + maxn] - cnt1 - cnt2;
int len = del[u].size();
for (int i = 0;i < len;i += 2){
int st = del[u][i];
int ed = del[u][i + 1];
int dis = deep[st] + deep[ed] - 2 * deep[u];
cnt[deep[st]] --;
cnt[deep[ed] - dis + maxn] --;
if (deep[u] - t[u] == deep[ed] - dis) ans[u] --;
}
}
int main(){
memset(head, -1, sizeof(head));
memset(qhead, -1, sizeof(qhead));
n = read(); m = read();
for (int i = 1;i < n;i ++){
int u, v;
u = read();
v = read();
add(u, v);
add(v, u);
}
for (int i = 1;i <= n;i ++) t[i] = read();
for (int i = 1;i <= m;i ++){
int u, v;
u = read();
v = read();
qadd(u, v);
qadd(v, u);
}deep[1] = 1;
Dfs(1, 1);
tarjan(1);
for (int i = 0;i < m;i ++){
int lca = qes[i*2].lca;
int u = qes[i*2].fro;
int v = qes[i*2].to;
del[lca].push_back(u);
del[lca].push_back(v);
}
dfs(1, 1, 0, 0);
for (int i = 1;i <= n;i ++) printf("%d ", ans[i]);
}
by zzozz @ 2017-10-11 15:20:22
没有灵性
by powerLEO101 @ 2017-10-12 06:36:05
by dengyixuan @ 2017-10-19 23:16:08
数组开大一倍,一开始我也是这样的