Codeforce 342E - Xenia and Tree(LCA+spfa,5级)
复杂度<sqrt(m)*m;
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<cmath> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) #define ll(x) (1<<x) using namespace std; const int msize=4e5+9; const int oo=1e9; int head[msize],edge; int to[msize],rmq[msize][33]; bool vis[msize]; int n,m; queue<int>Q; class Edge { public:int v,next; }e[msize+msize]; void data() { clr(head,-1);edge=0; } void add(int u,int v) { e[edge].v=v;e[edge].next=head[u];head[u]=edge++; } int dep[msize],dfs_clock,e_c[msize],dis[msize]; void dfs(int u,int dd) { dep[u]=dd; to[dfs_clock]=u; e_c[u]=dfs_clock++; int v; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; if(e_c[v]==-1) { dfs(v,dd+1); to[dfs_clock++]=u; } } } int bit[msize]; void initRMQ() { bit[0]=-1; int n=dfs_clock; FOR(i,1,n)bit[i]=(i&(i-1))==0?bit[i-1]+1:bit[i-1]; FOR(i,0,n-1)rmq[i][0]=dep[ to[i] ]; FOR(i,1,bit[n]) for(int j=0;j+ll(i)-1<n;++j) rmq[j][i]=min(rmq[j][i-1],rmq[j+ll(i-1)][i-1]); } int RMQ(int l,int r) { l=e_c[l];r=e_c[r]; if(l>r)swap(l,r); int t=bit[r-l+1]; r-=ll(t)-1; return min(rmq[l][t],rmq[r][t]); } void getclear() { dfs_clock=0; clr(e_c,-1); clr(dis,0x3f); } void spfa() { clr(vis,0); int u,v; while(!Q.empty()) { u=Q.front();Q.pop();vis[u]=0; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; if(dis[v]>dis[u]+1) { dis[v]=dis[u]+1; if(!vis[v]) { Q.push(v); vis[v]=1; } } } } } int getdis(int l,int r) { int lca=RMQ(l,r); // printf("e=%d %d\ne=%d %d\nlca=%d\n",l,dep[l],r,dep[r],lca); return dep[l]+dep[r]-lca*2; } int main() { int a,b; while(~scanf("%d%d",&n,&m)) { data(); FOR(i,2,n) { scanf("%d%d",&a,&b); add(a,b);add(b,a); } int block=sqrt(m); getclear(); dfs(1,0); initRMQ(); Q.push(1); dis[1]=0; // puts("+++"); FOR(i,1,m) { scanf("%d%d",&a,&b); if(a==1) { Q.push(b);dis[b]=0; } else if(a==2) { int sz=Q.size(); if(sz>block) { spfa(); printf("%d\n",dis[b]); } else { int ans=dis[b]; int bg=-1; while(!Q.empty()) { int q=Q.front(); if(bg==-1)bg=q; else if(bg==q)break; Q.pop(); // puts("_+)+"); // printf("d=%d %d\n",b,q); ans=min(ans,getdis(b,q)); Q.push(q); } printf("%d\n",ans); } } } } return 0; }
The article write by nealgavin