zoukankan      html  css  js  c++  java
  • CF757F-Team Rocket Rises Again【最短路,DAG支配树】

    正题

    题目链接:https://www.luogu.com.cn/problem/CF757F


    题目大意

    (n)个点(m)条边的一张无向图,求删除(s)以外的一个点改变(s)到最多点的最短路。


    解题思路

    挺裸的一道题的,首先肯定要跑一遍最短路搞出最短路树。

    然后如果最短路树上(s)到某个点的路径被割掉了就会改变最短路长度,所以直接求出支配树然后看除了根以外最大子树的子节点就好了。

    时间复杂度(O(mlog n))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    #define mp(x,y) make_pair(x,y)
    using namespace std;
    const ll N=3e5+10,T=19;
    priority_queue<pair<ll,ll>> q;
    struct node{
        ll to,next,w;
    }a[N*2];
    ll n,m,s,tot,ls[N],dis[N],dep[N],v[N];
    ll head,tail,top[N],f[N][T+1],siz[N];
    void addl(ll x,ll y,ll w){
        a[++tot].to=y;
        a[tot].next=ls[x];
        ls[x]=tot;a[tot].w=w;
        return;
    }
    void dij(){
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;q.push(mp(0,s));
        while(!q.empty()){
            ll x=q.top().second;q.pop();
            if(v[x])continue;v[x]=1;
            for(ll i=ls[x];i;i=a[i].next){
                ll y=a[i].to;
                if(dis[x]+a[i].w<dis[y]){
                    dis[y]=dis[x]+a[i].w;
                    q.push(mp(-dis[y],y));
                }
            }
        }
        return;
    }
    ll LCA(ll x,ll y){
        if(dep[x]>dep[y])swap(x,y);
        for(ll i=T;i>=0;i--)
            if(dep[f[y][i]]>=dep[x])
                y=f[y][i];
        if(x==y)return x;
        for(ll i=T;i>=0;i--)
            if(f[x][i]!=f[y][i])
                x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    void build(){
        head=1;tail=1;top[1]=s;
        memset(v,0,sizeof(v));
        for(ll x=1;x<=n;x++)
            for(ll i=ls[x];i;i=a[i].next)
                if(dis[x]+a[i].w==dis[a[i].to])
                    v[a[i].to]++;
        while(head<=tail){
            ll x=top[head++];
            dep[x]=dep[f[x][0]]+1;
            for(ll i=1;i<=T;i++)
                f[x][i]=f[f[x][i-1]][i-1];
            for(ll i=ls[x];i;i=a[i].next){
                ll y=a[i].to;
                if(dis[x]+a[i].w!=dis[y])continue;
                v[y]--;
                if(!f[y][0])f[y][0]=x;
                else f[y][0]=LCA(f[y][0],x);
                if(!v[y])top[++tail]=y;
            }
        }
        return;
    }
    signed main()
    {
        scanf("%lld%lld%lld",&n,&m,&s);
        for(ll i=1;i<=m;i++){
            ll x,y,w;
            scanf("%lld%lld%lld",&x,&y,&w);
            addl(x,y,w);addl(y,x,w);
        }
        dij();
        build();ll ans=0;
        for(ll i=tail;i>1;i--){
            siz[top[i]]++,siz[f[top[i]][0]]+=siz[top[i]];
            ans=max(ans,siz[top[i]]);
        }
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    ER模型
    一道人人的笔试题
    关系代数运算
    推荐两个不错的CAD二次开发(.Net)手册
    CAD 致命错误
    CAD二次开发(.NET)之PaletteSet和Palette
    养生
    我看面向对象
    .NET中参数化查询数据库
    自定义按照index和key访问的List
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14285416.html
Copyright © 2011-2022 走看看