社区讨论
复杂度是不是假了
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 3已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mii4h28u
- 此快照首次捕获于
- 2025/11/28 08:26 3 个月前
- 此快照最后确认于
- 2025/11/29 13:25 3 个月前
T 的只剩 分了。
CPP#include<bits/extc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 2.5e5 + 5;
int n,m,k,tim,idx;
bool imp[maxn];
int st[20][maxn];
int dp[maxn],h[maxn],vec[maxn];
int fa[maxn],son[maxn],top[maxn],rnk[maxn];
int siz[maxn],dep[maxn],dfn[maxn],val[maxn];
class graph
{
public:
int head[maxn],idx;
struct{int v,w,nxt;}e[maxn << 1];
void adde(int u,int v,int w)
{
e[++idx] = {v,w,head[u]};
head[u] = idx;
}
}g1,g2;
void dfs1(int u,int pre)
{
fa[u] = pre,siz[u] = 1;
dep[u] = dep[pre] + 1;
for (int i = g1.head[u],v; i; i = g1.e[i].nxt)
{
if ((v = g1.e[i].v) == pre)
continue;
val[v] = g1.e[i].w;
dfs1(v,u);
siz[u] += siz[v];
if (siz[v] > siz[son[u]])
son[u] = v;
}
}
void dfs2(int u,int tp)
{
dfn[u] = ++tim,rnk[tim] = u;
top[u] = tp;
if (son[u])
dfs2(son[u],tp);
for (int i = g1.head[u],v; i; i = g1.e[i].nxt)
if ((v = g1.e[i].v) != fa[u] && v != son[u])
dfs2(v,v);
}
int lca(int u,int v)
{
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap(u,v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
int que(int l,int r)
{
if (l > r)
return inf;
int k = __lg(r - l + 1);
return min(st[k][l],st[k][r - (1LL << k) + 1]);
}
int query(int u,int v)
{
int res = inf;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap(u,v);
res = min(res,que(dfn[top[u]],dfn[u]));
u = fa[top[u]];
}
if (dep[u] < dep[v])
swap(u,v);
res = min(res,que(dfn[v] + 1,dfn[u]));
return res;
}
bool cmp(int x,int y){return dfn[x] < dfn[y];}
void dfs3(int u)
{
for (int i = g2.head[u],v; i; i = g2.e[i].nxt)
{
v = g2.e[i].v,dfs3(v);
if (imp[v])
dp[u] += g2.e[i].w;
else
dp[u] += min(g2.e[i].w,dp[v]);
}
}
void solve()
{
cin >> k;
for (int i = 1; i <= k; i++)
cin >> h[i],imp[h[i]] = 1;
sort(h + 1,h + k + 1,cmp);
vec[idx = 1] = 1;
vec[++idx] = h[1];
for (int i = 2; i <= k; i++)
{
vec[++idx] = h[i];
vec[++idx] = lca(h[i - 1],h[i]);
}
sort(vec + 1,vec + idx + 1,cmp);
idx = unique(vec + 1,vec + idx + 1) - vec - 1;
for (int i = 2; i <= idx; i++)
{
int anc = lca(vec[i - 1],vec[i]);
g2.adde(anc,vec[i],query(vec[i],anc));
}
dfs3(1),cout << dp[1] << '\n';
for (int i = 1; i <= idx; i++)
g2.head[i] = dp[i] = imp[vec[i]] = 0;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1,u,v,w; i < n; i++)
{
cin >> u >> v >> w;
g1.adde(u,v,w);
g1.adde(v,u,w);
}
dfs1(1,0),dfs2(1,1);
for (int i = 1; i <= n; i++)
st[0][i] = val[rnk[i]];
for (int i = 1; i < 20; i++)
for (int j = 1; j + (1LL << i) - 1 <= n; j++)
st[i][j] = min(st[i - 1][j],st[i - 1][j + (1LL << (i - 1))]);
cin >> m;
while (m--)
solve();
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...