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 }

 

posted @ 2018-10-18 16:56  Ressed  阅读(563)  评论(0编辑  收藏  举报