但是要考虑封城的问题,把每个点封城的若干段时间区间存下来依次按编号、时间排序,注意最后可能有城市直到操作结束都没解封也要算上。在最短路中转移的时候,设当前从
x
x
x转移到
y
y
y,则通过二分找到在
d
i
s
x
dis_x
disx后面最近的且
x
x
x和
y
y
y都没被封城的时间
t
t
t,用
t
t
t更新
d
i
s
y
dis_y
disy。
具体做法的话,先一次二分找到只满足
x
x
x没被封的时间,再找该时间后
y
y
y没被封的时间,若相同则退出,否则
x
x
x和
y
y
y交替找下去。
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>usingnamespace std;#define N 500010int last[N], nxt[N *2], to[N *2], len =0;int a[N], p[N], s =0, tot =0;int dis[N], vi[N];struct ci {int x, l, r;}lo[N];struct{int x, t;}qu[N];
queue<int> q;intcmp(ci x, ci y){if(x.x == y.x)return x.l < y.l;return x.x < y.x;}voidadd(int x,int y){
to[++len]= y;
nxt[len]= last[x];
last[x]= len;}intread(){char x =getchar();int s =0;while(x <'0'|| x >'9') x =getchar();while(x >='0'&& x <='9') s = s *10+ x -48, x =getchar();return s;}intfind(int x,int t){int l =1, r = s, R =0;while(l <= r){int mid =(l + r)/2;if(lo[mid].x > x) r = mid -1;elseif(lo[mid].x < x) l = mid +1;else{if(lo[mid].l <= t) R = lo[mid].r, l = mid +1;else r = mid -1;}}
R =max(t, R);return R;}intmain(){int i, n =read(), m =read(), Q =read(), x, y;for(i =1; i < n; i++){
x =read(), y =read();add(x, y),add(y, x);}for(i =1; i <= m; i++) a[i]=read();int t =0;memset(p,255,sizeof(p));for(i =1; i <= Q; i++){int op =read();if(op ==1){
p[read()]= t;}elseif(op ==2){
x =read();if(p[x]!= t) lo[++s].x = x, lo[s].l = p[x], lo[s].r = t;
p[x]=-1;}elseif(op ==3){
qu[++tot].x =read(), qu[tot].t = t;}elseif(op ==4){
t++;}}for(i =1; i <= n; i++)if(p[i]!=-1){
lo[++s].x = i, lo[s].l = p[i], lo[s].r = t;}sort(lo +1, lo + s +1, cmp);for(i = s -1; i >0; i--){if(lo[i +1].x == lo[i].x && lo[i].r >= lo[i +1].l) lo[i].r = lo[i +1].r;}memset(dis,127,sizeof(dis));for(i =1; i <= m; i++){
vi[a[i]]=1, dis[a[i]]=0;
q.push(a[i]);}while(!q.empty()){
x = q.front();
q.pop();int out =find(x, dis[x]);for(i = last[x]; i; i = nxt[i]){
y = to[i];int ti = out, in;while(ti +1< dis[y]){
in =find(y, ti);
ti =find(x, in);if(ti == in)break;}if(ti +1< dis[y]){
dis[y]= ti +1;if(!vi[y]){
vi[y]=1;
q.push(y);}}}
vi[x]=0;}for(i =1; i <= tot; i++){if(dis[qu[i].x]<= qu[i].t)puts("Y");elseputs("N");}return0;}