Night_sea_64 @ 2023-06-08 19:43:39
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int n,m,k,d[10010],sz[10010],maxpart[10010];
struct edge{int x,w;bool f;};
vector<edge>v[10010],v2[10010];
int a[10010],cur;
bool flag[10000010],ans;
void dfs1(int x,int last)
{
sz[x]=1;
for(int i=0;i<v[x].size();i++)if(v[x][i].f)
if(v[x][i].x!=last)
{
dfs1(v[x][i].x,x);
sz[x]+=sz[v[x][i].x];
maxpart[x]=max(maxpart[x],sz[v[x][i].x]);
}
}
int find(int x)
{
for(int i=1;i<=n;i++)
maxpart[i]=sz[i]=0;
dfs1(x,0);
int minn=1e9,minid=0;
for(int i=1;i<=n;i++)
{
maxpart[i]=max(maxpart[i],sz[x]-sz[i]);
if(maxpart[i]<minn)
minn=maxpart[i],minid=i;
}
return minid;
}
void dfs2(int x,int last)
{
if(d[x]>k)return;
if(flag[k-d[x]])ans=1;
if(ans)return;
for(int i=0;i<v[x].size();i++)
if(v[x][i].x!=last)
{
d[v[x][i].x]=d[x]+v[x][i].w;
dfs2(v[x][i].x,x);
}
}
void dfs3(int x,int last)
{
if(d[x]>k)return;
if(!flag[d[x]])
{
flag[d[x]]=1;
a[++cur]=d[x];
}
for(int i=0;i<v[x].size();i++)
if(v[x][i].x!=last)
dfs3(v[x][i].x,x);
}
void solve(int x)
{
x=find(x);
memset(d,0,sizeof(d));
flag[0]=1;
a[++cur]=0;
for(int i=0;i<v[x].size();i++)if(v[x][i].f)
{
d[v[x][i].x]=v[x][i].w;
dfs2(v[x][i].x,x);
dfs3(v[x][i].x,x);
}
for(int i=1;i<=cur;i++)
flag[a[i]]=0;
cur=0;
if(ans)return;
v2[x]=v[x];
for(int i=1;i<=n;i++)
for(int j=0;j<v[i].size();j++)
if(i==x||v[i][j].x==x)v[i][j].f=0;
for(int i=0;i<v2[x].size();i++)if(v2[x][i].f)
solve(v[x][i].x);
}
int main()
{
cin>>n>>m;
for(int i=1;i<n;i++)
{
int x,y,w;
cin>>x>>y>>w;
v[x].push_back({y,w,1});
v[y].push_back({x,w,1});
}
while(m--)
{
ans=0;
for(int i=1;i<=n;i++)
for(int j=0;j<v[i].size();j++)
v[i][j].f=1;
cin>>k;
solve(1);
cout<<(ans?"AYE":"NAY")<<endl;
}
return 0;
}
我的代码 T 了四个点(如果把找重心那里删掉只会 T 三个),请问我应该优化哪里呢?
by Night_sea_64 @ 2023-06-08 19:48:00
哦,看到了 https://www.luogu.com.cn/discuss/188596 我先改成只点分治一次
by cjwdyzxfblzs @ 2023-06-08 20:08:46
@Netherite_sword_666 不能每次跑一个,应该离线下来,查看询问,跑一次
by Night_sea_64 @ 2023-06-08 20:34:51
@sjzez__chess 感谢大佬,我就打算这么改了