zoukankan      html  css  js  c++  java
  • bzoj2125 最短路

    题目描述:

    bz

    题解:

    圆方树。

    将仙人掌搞成圆方树后将设方圆边边权设为圆点到环的顶点的最短距离。

    这样的话询问时求一下$lca$,然后讨论。

    若$lca$是圆点,直接返回距离。

    若$lca$是方点,讨论环上的两个点是在同一方向到顶点还是在不同方向到顶点。

    然后代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 10050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,m,q,hed[N],cnt=1;
    struct EG
    {
        int to,nxt;
        ll w;
    }e[N<<2];
    void ae(int f,int t,ll w)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        e[cnt].w = w;
        hed[f] = cnt;
    }
    ll c[N<<1],d[N];
    int dfn[N],low[N],tim,dep[N<<1];
    int fa[N],r[N],tr;
    int ff[N<<1][20];
    ll md[N<<1][20];
    int typ[N<<1];
    int get_d(int x){return dep[x]?dep[x]:dep[x]=get_d(ff[x][0])+1;}
    void fl(int u,int f,ll w)
    {
        ff[u][0] = f;
        md[u][0] = w;
    }
    void sol(int u,int v,ll w)
    {
        r[tr=1] = u;
        ll sum = w;
        while(v!=u)sum+=d[v],r[++tr]=v,v=fa[v];
        int now = ++n;
        fl(now,u,0);
        ll dis = w;
        for(int i=2;i<=tr;i++)
        {
            fl(r[i],now,min(dis,sum-dis));
            typ[r[i]]=(dis<sum-dis);
            dis+=d[r[i]];
        }
        c[now] = sum;
    }
    void tarjan(int u,int pre)
    {
        dfn[u] = low[u] = ++tim;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(j==pre)continue;
            if(!dfn[to])
            {
                fa[to] = u,d[to] = e[j].w;
                tarjan(to,j^1);
                low[u] = min(low[u],low[to]);
            }else    low[u] = min(low[u],dfn[to]);
            if(low[to]>dfn[u])fl(to,u,e[j].w);
        }
        for(int to,j=hed[u];j;j=e[j].nxt)
            if(fa[to=e[j].to]!=u&&dfn[to]>dfn[u])
                sol(u,to,e[j].w);
    }
    void init()
    {
        for(int i=1;i<=n;i++)get_d(i);
        for(int k=1;(1<<k)<=n;k++)
            for(int i=1;i<=n;i++)
                ff[i][k]=ff[ff[i][k-1]][k-1],md[i][k]=md[i][k-1]+md[ff[i][k-1]][k-1];
    }
    int get_lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=18;i>=0;i--)
            if(dep[ff[x][i]]>=dep[y])x=ff[x][i];
        if(x==y)return x;
        for(int i=18;i>=0;i--)
            if(ff[x][i]!=ff[y][i])x=ff[x][i],y=ff[y][i];
        return ff[x][0];
    }
    ll get_dis(int x,int y)
    {
        ll ret = 0;
        if(dep[x]<dep[y])swap(x,y);
        for(int i=18;i>=0;i--)
            if(dep[ff[x][i]]>=dep[y])ret+=md[x][i],x=ff[x][i];
        if(x==y)return ret;
        for(int i=18;i>=0;i--)
            if(ff[x][i]!=ff[y][i])ret+=md[x][i]+md[y][i],x=ff[x][i],y=ff[y][i];
        return ret+md[x][0]+md[y][0];
    }
    int get_son(int x,int y)
    {
        for(int i=18;i>=0;i--)
            if(dep[ff[x][i]]>dep[y])x=ff[x][i];
        return x;
    }
    ll query(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        int z = get_lca(x,y);
        ll w = get_dis(x,y);
        if(!c[z])return w;
        x = get_son(x,z),y = get_son(y,z);
        ll ta = md[x][0],tb = md[y][0];
        ll tmp = (typ[x]==typ[y])?abs(ta-tb):(ta+tb);
        return w-ta-tb+min(tmp,c[z]-tmp);
    }
    int main()
    {
        read(n),read(m),read(q);
        for(int f,t,w,i=1;i<=m;i++)
        {
            read(f),read(t),read(w);
            ae(f,t,w),ae(t,f,w);
        }
        dep[1]=1;
        tarjan(1,0);
        init();
        for(int x,y,i=1;i<=q;i++)
        {
            read(x),read(y);
            printf("%lld
    ",query(x,y));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    hdu1050 Moving Tables
    初读《数学之美》........................(2)
    初读《数学之美》........................(1)
    zju1058 Currency Exchange
    hdu 2391 Filthy Rich
    hdu1029 Ignatius and the Princess IV(统计)
    hdu1072 Nightmare (BFS)
    apache2.2 + tomcat 6 集群
    权限管理系统实现:
    设置页面那些ID对应的对象隐藏setDisplay
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10818949.html
Copyright © 2011-2022 走看看