JZOJ 4811. 排队

题目

Description

 

Input

Output

 

Sample Input

5 4
1 2
1 3
3 4
3 5
1 4
2 4
1 2
2 5

Sample Output

3
1
1
2
 

Data Constraint


 

Hint

 

 

分析

 

 

  • 这道题一看应该是个模拟题

  • 但是我们需要优化

  • 首先我们要跑一个dfs,讲树的优先级跑出来

  • 然后我们开一个优先队列

  • 讲优先级的下标压进队列

  • 然后我们用倍增优化我们的向上找第一个被标记的点

  • 结果就是直接的深度

 

代码

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 #include <queue>
 5 #include<cstdio>
 6 using namespace std;
 7 const int N=100010;
 8 int n,t,tot,cnt,ans,dfx[N],d[N],p[N],deep[N],f[N][20];
 9 bool bz[N];
10 priority_queue<int,vector<int>,greater<int> > q;
11 vector<int> a[N];
12 bool cmp(int x,int y) { return dfx[x]<dfx[y]; }
13 void dfs(int x,int fa)
14 {
15     f[x][0]=fa,deep[x]=deep[fa]+1;
16     for (int i=0;i<a[x].size();i++) if (a[x][i]!=fa) dfs(a[x][i],x); 
17     dfx[x]=++cnt;
18 }
19 int main ()
20 {
21     cin>>n>>t;
22     for (int i=1,x,y;i<=n-1;i++)
23     {
24         scanf("%d %d",&x,&y); 
25         a[x].push_back(y);
26         a[y].push_back(x);
27     }
28     for (int i=1;i<=n;i++) d[i]=i,sort(a[i].begin(),a[i].end());
29     dfs(1,0);
30     for (int i=1;i<=18;i++)
31         for (int j=1;j<=n;j++)
32           f[j][i]=f[f[j][i-1]][i-1];
33     sort(d+1,d+1+n,cmp);
34     for (int i=1;i<=n;i++) p[d[i]]=i;
35     for (int i=1;i<=n;i++) q.push(i);
36     for (int i=1,x,y,op;i<=t;i++)
37     {
38         scanf("%d %d",&op,&x);
39         if(op==1)
40         {
41             for (;x;x--) bz[ans=d[q.top()]]=1,q.pop();
42             printf("%d\n",ans);
43         }
44         else
45         {
46             int a=x;
47             for (int i=18;i>=0;i--)
48               if (bz[f[a][i]]) a=f[a][i];
49             bz[a]=0,q.push(p[a]);
50             printf("%d\n",deep[x]-deep[a]);
51         }
52      } 
53 }

 

 

 

posted @ 2019-07-03 22:03  Melted_czj  阅读(87)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色