Codeforces 757F. Team Rocket Rises Again
阿新 • • 發佈:2018-07-15
ORC swap cin long long head rip n) typedef ems
我們就在滅絕樹上連邊 \((lca,x)\) , 最後統計一遍 \(max(size[i])\) 就是答案
Description
給出 \(n\) 個點 \(m\) 條邊的無向圖 , 和一個起點 \(S\) ,問讓你刪除一個點和與這個點相連的邊,你可以選擇刪除一個點, 最大化到 \(S\) 的最短路發生改變的點數
題面
Solution
按照最短路為拓撲序建立滅絕樹
滅絕樹的定義是:如果一個點滅絕,那麽它的子樹內的點都會滅絕
\(dis[u]+l=dis[x]\) ,那麽刪除這個點就會導致最短路發生變化,如果有多個點都滿足,刪除所有的才會發生變化
那麽怎麽才能刪除一個點使得它變化?刪除所有滿足 \(dis[u]+l=dis[x]\) 的 \(u\) 的 \(lca\),或者 \(lca\) 以上的點即可
#include<bits/stdc++.h> using namespace std; template<class T>void gi(T &x){ int f;char c; for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f; } typedef long long ll; const int N=2e5+10; int n,m,S,dis[N*4],head[N],nxt[N*4],to[N*4],num=0,q[N],top=0; inline void link(int x,int y,int z){ nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z; nxt[++num]=head[y];to[num]=x;head[y]=num;dis[num]=z; } ll f[N];int fa[N][20],dep[N],sz[N]; struct data{int x;ll y;}; inline bool operator <(data i,data j){return i.y>j.y;} priority_queue<data>Q; inline void dj(){ memset(f,127/3,sizeof(f)); Q.push((data){S,0});f[S]=0; while(!Q.empty()){ while(f[Q.top().x]!=Q.top().y)Q.pop(); int x=Q.top().x;Q.pop();q[++top]=x; if(top==n)break; for(int i=head[x];i;i=nxt[i]){ int u=to[i]; if(f[x]+dis[i]<f[u])f[u]=f[x]+dis[i],Q.push((data){u,f[u]}); } } } inline int lca(int x,int y){ if(dep[x]<dep[y])swap(x,y); for(int i=18;i>=0;i--)if((dep[x]-dep[y])>>i&1)x=fa[x][i]; if(x==y)return x; for(int i=18;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); int x,y,z; cin>>n>>m>>S; for(int i=1;i<=m;i++){ gi(x);gi(y);gi(z); link(x,y,z); } dj(); for(int i=1;i<=top;i++){ x=q[i];z=-1; for(int j=head[x];j;j=nxt[j]){ y=to[j]; if(f[y]+dis[j]==f[x]){ if(z==-1)z=y; else z=lca(y,z); } } if(z==-1)continue; dep[x]=dep[z]+1,fa[x][0]=z; for(int j=1;j<=18;j++)fa[x][j]=fa[fa[x][j-1]][j-1]; } for(int i=1;i<=n;i++)sz[i]=1; int ans=0; for(int i=top;i>=1;i--){ x=q[i]; sz[fa[x][0]]+=sz[x]; if(x!=S)ans=max(ans,sz[x]); } cout<<ans<<endl; return 0; }
Codeforces 757F. Team Rocket Rises Again