P3942
Posted vimin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3942相关的知识,希望对你有一定的参考价值。
题目传送P3942
思路
- 是P2279消防局的设立的加强版
- 我们只需要每次找到最深的点,然后找到向上距离他 $k$ 个深度的祖先
- 话说只要在之前的代码改几个地方就行
- 可我偏偏调了一晚上
- 数据到了1e5
- 到大数据就莫名死循环
- 改了下
- 还是TLE
- TLE的原因 是每次把选中点距离为 $k$ 的点标记,要记录前一个点,而不能直接用它的父亲,因为并不准确,我们可能向下走也可能向上走,上一个走过来的不一定是父亲。需要单独记录。
死循化 的原因好像是弹出队列时死循环了
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
#pragma GCC optimize(2)
using namespace std;
int n,tot,ans,k,t;
bool vis[100005];
int head[100005];
int dep[100005],fa[100005];
struct node
int to,net;
e[200005];
struct cmp
bool operator () (int &a,int &b)
return dep[a]<dep[b];
;
priority_queue<int,vector<int>,cmp>q;
inline void add(int x,int y)
e[++tot].to =y,e[tot].net=head[x],head[x]=tot;
e[++tot].to =x,e[tot].net=head[y],head[y]=tot;
inline void dfs1(int x,int f,int depth)
fa[x]=f;
dep[x]=depth;
for(int i=head[x];i;i=e[i].net )
int to=e[i].to ;
if(to==f) continue;
dfs1(to,x,depth+1);
inline void dfs2(int x,int from,int depth)
if(depth>k) return ;
vis[x]=1;
for(int i=head[x];i;i=e[i].net )
if(e[i].to !=from)dfs2(e[i].to ,x,depth+1);
void cal(int x)
int num=0;
while(num<k)
num++;
x=fa[x];
t=x;
/*if(x==0)
t=x;
return ;
if(num==k)
t=x;
return ;
cal(fa[x],num+1);*/
inline int read()
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9') if(ch=='-') w=-1;ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
int main()
// freopen("63.in","r",stdin);
// freopen("63.out","w",stdout);
n=read();k=read();t=read();
// scanf("%d%d%d",&n,&k,&t);
for(int i=1;i<n;i++)
int x,y;
x=read();y=read();
// scanf("%d%d",&x,&y);
add(x,y);
dfs1(1,0,1);
for(int i=1;i<=n;i++) q.push(i);
int x;
while(q.size())
x=q.top() ;q.pop();
if(vis[x]) continue ;
// while(q.size()&&vis[x=q.top()]) q.pop();
// cout<<"DE"<<endl;
cal(x);
if(t) dfs2(t,t,0);
else dfs2(1,1,0);
ans++;
printf("%d",ans);
return 0;
以上是关于P3942的主要内容,如果未能解决你的问题,请参考以下文章