cf757F Team Rocket Rises Again (dijkstra+支配树)
我也想要皮卡丘
跑一遍dijkstra,可以建出一个最短路DAG(从S到任意点的路径都是最短路),然后可以在上面建支配树
并不会支配树,只能简单口胡一下在DAG上的做法
建出来的支配树中,某点的祖先集就是从S到该点的必经点集,也就是说,炸掉某点,这个子树都会变得angryunhappy
大概就是按拓扑序来建这个树,每条边(u,v)是要把fa[v]=lca(u,fa[v]),等到v的入度为零时,再用最终的fa[v]连到v上,然后给v做以后求lca时倍增的预处理
最后dfs算出来除S点的最大的子树大小就是答案
1 #include<bits/stdc++.h> 2 #define pa pair<ll,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=2e5+10,maxm=3e5+10; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 struct Edge{ 16 int a,b,l,ne; 17 }eg[maxm*2]; 18 int egh[maxn],ect; 19 int N,M,S; 20 int fa[maxn][20],bro[maxn],sh[maxn],dep[maxn]; 21 int siz[maxn],ans,ine[maxn]; 22 ll dis[maxn]; 23 priority_queue<pa,vector<pa>,greater<pa> > q; 24 queue<int> q2; 25 bool flag[maxn]; 26 27 inline void adeg(int a,int b,int c){ 28 eg[++ect].a=a;eg[ect].b=b;eg[ect].l=c; 29 eg[ect].ne=egh[a];egh[a]=ect; 30 } 31 32 inline void dijkstra(){ 33 CLR(dis,127); 34 dis[S]=0;q.push(make_pair(0,S)); 35 while(!q.empty()){ 36 int p=q.top().second;q.pop(); 37 if(flag[p]) continue; 38 flag[p]=1; 39 for(int i=egh[p];i;i=eg[i].ne){ 40 int b=eg[i].b; 41 if(dis[b]>dis[p]+eg[i].l){ 42 dis[b]=dis[p]+eg[i].l; 43 q.push(make_pair(dis[b],b)); 44 } 45 } 46 } 47 } 48 49 int getlca(int x,int y){ 50 if(dep[x]<dep[y]) swap(x,y); 51 for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){ 52 if(fa[x][i]&&dep[fa[x][i]]>=dep[y]) 53 x=fa[x][i]; 54 } 55 if(x==y) return x; 56 for(int i=log2(dep[x]);i>=0;i--){ 57 if(fa[x][i]!=fa[y][i]) 58 x=fa[x][i],y=fa[y][i]; 59 } 60 return fa[x][0]; 61 } 62 63 void dfs(int x){ 64 siz[x]=1; 65 for(int i=sh[x];i;i=bro[i]){ 66 dfs(i); 67 siz[x]+=siz[i]; 68 } 69 if(x!=S) ans=max(ans,siz[x]); 70 } 71 72 int main(){ 73 //freopen("","r",stdin); 74 int i,j,k; 75 N=rd(),M=rd();S=rd(); 76 for(i=1;i<=M;i++){ 77 int a=rd(),b=rd(),c=rd(); 78 adeg(a,b,c);adeg(b,a,c); 79 } 80 dijkstra(); 81 for(i=1;i<=ect;i++){ 82 int a=eg[i].a,b=eg[i].b; 83 if(dis[a]+eg[i].l==dis[b]){ 84 ine[b]++; 85 } 86 } 87 q2.push(S);dep[S]=1; 88 while(!q2.empty()){ 89 int p=q2.front();q2.pop(); 90 for(i=egh[p];i;i=eg[i].ne){ 91 int b=eg[i].b; 92 if(eg[i].l+dis[p]==dis[b]){ 93 fa[b][0]=fa[b][0]?getlca(p,fa[b][0]):p; 94 ine[b]--; 95 if(!ine[b]){ 96 dep[b]=dep[fa[b][0]]+1; 97 for(j=0;fa[b][j]&&fa[fa[b][j]];j++) 98 fa[b][j+1]=fa[fa[b][j]][j]; 99 q2.push(b); 100 } 101 } 102 } 103 } 104 for(i=1;i<=N;i++){ 105 // printf("%d %d\n",i,fa[i][0]); 106 if(i==S||!fa[i][0]) continue; 107 bro[i]=sh[fa[i][0]],sh[fa[i][0]]=i; 108 } 109 dfs(S); 110 printf("%d\n",ans); 111 return 0; 112 }