问题出现在树链剖分的dfs1和dfs2部分,首先是使用链式前向星存图的方式,已经判断出来会出现栈溢出。
//fa[x]为x的父节点,siz[x]为以x为根的子树大小,deep[x]为x的深度,son[x]为x的重儿子,top[x]为x所在重链顶,id[x]为x的dfs序,w[x]为X的权值。
struct EDGE{
int to, next;
}edge[N << 1];
int head[N << 1], cnt = 0;
void add(int x, int y)
{
edge[++cnt].to = y;
edge[cnt].next = head[x];
head[x] = cnt;
}
void dfs1(int x, int father)
{
deep[x] = deep[father] + 1;
fa[x] = father;
siz[x] = 1;
for(int i = head[x]; i; i = edge[i].next)
{
int y = edge[i].to;
if(y != father)
{
fa[y] = x;
dfs1(y, x);
siz[x] += siz[y];
if(!son[x] || siz[son[x]] < siz[y])
son[x] = y;
}
}
}
void dfs2(int x, int topx)
{
id[x] = ++num;
w_new[num] = w[x];
top[x] = topx;
if(!son[x])
return;
dfs2(son[x], topx);
for(int i = head[x]; i; i = edge[i].next)
{
int y = edge[i].to;
if(y != fa[x] && y != son[x])
dfs2(y, y);
}
}
void init()
{
for(int i = 0; i < (N << 1); i++)
edge[i].next = head[i] = 0;
for(int i = 0; i <= N; i++)
son[i] = id[i] = fa[i] = deep[i] = siz[i] = top[i] = 0;
cnt = 0;
}
void solve()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> w[i];
for(int i = 1; i < n; i++)
{
int x, y;
cin >> x >> y;
add(x, y);
add(y, x);
}
init();
//涉及出错部分如上
}下面是使用vector存图的部分,不会出现栈溢出。
struct Graph{
vector<vector<int> > table;
void init(int _n) { table.assign(_n + 1, {}); }
void add(int u, int v)
{
table[u].push_back(v);
}
}G;
void dfs1(int x, int father)
{
deep[x] = deep[father] + 1;
fa[x] = father;
siz[x] = 1;
for (int v : G.table[x])
{
if (v == father) continue;
dfs1(v, x);
siz[x] += siz[v];
if (siz[v] > siz[son[x]])
son[x] = v;
}
}
void dfs2(int x, int topx)
{
id[x] = ++num;
w_new[num] = w[x];
top[x] = topx;
if(!son[x])
return;
dfs2(son[x], topx);
for (int v : G.table[x])
{
if (v == fa[x] || v == son[x])
continue;
dfs2(v, v);
}
}
void init()
{
num = 0;
for (int i = 0; i <= n; ++i)
{
son[i] = id[i] = fa[i] = deep[i] = siz[i] = top[i] = 0;
tag[i] = 0;
}
G.init(n);
}
void solve()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> w[i];
init();
for(int i = 1; i < n; i++)
{
int x, y;
cin >> x >> y;
G.add(x, y);
//cout << 1 << endl;
G.add(y, x);
}
}