zoukankan      html  css  js  c++  java
  • BZOJ 3694 最短路

    233333想简单了。。。。

    题解参见http://hzwer.com/3710.html

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 4050
    #define maxe 200500
    #define inf 0x7f7f7f7f7f7f7f7fLL
    using namespace std;
    struct edge
    {
        long long u,v,w,flag,nxt;
    }e[maxe];
    long long n,m,x,y,a,b,g[maxv],nume=0,dis[maxv];
    long long top[maxv],fath[maxv],dfn[maxv],dep[maxv],size[maxv],son[maxv],times=0;
    long long root,tot=0,ls[maxv<<2],rs[maxv<<2],lazy[maxv<<2];
    void addedge(long long u,long long v,long long w,long long flag)
    {
        e[++nume].u=u;
        e[nume].v=v;
        e[nume].w=w;
        e[nume].flag=flag;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs1(long long x)
    {
        size[x]=1;son[x]=0;
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if ((e[i].flag) && (v!=fath[x]))
            {
                fath[v]=x;dep[v]=dep[x]+1;dis[v]=dis[x]+e[i].w;
                dfs1(v);
                size[x]+=size[v];
                if (size[v]>size[son[x]]) son[x]=v;
            }
        }
    }
    void dfs2(long long x,long long father)
    {
        dfn[x]=++times;top[x]=father;
        if (son[x]) dfs2(son[x],father);
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if ((e[i].flag) && (v!=fath[x]) && (v!=son[x]))
                dfs2(v,v);
        }
    }
    void build(long long &now,long long left,long long right)
    {
        now=++tot;lazy[now]=inf;
        if (left==right) return;
        long long mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
    }
    void modify(long long now,long long left,long long right,long long l,long long r,long long x)
    {
        if ((left==l) && (right==r))
        {
            lazy[now]=min(lazy[now],x);
            return;
        }
        long long mid=(left+right)>>1;
        if (r<=mid) modify(ls[now],left,mid,l,r,x);
        else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x);
        else {modify(ls[now],left,mid,l,mid,x);modify(rs[now],mid+1,right,mid+1,r,x);}
    }
    long long lca(long long u,long long v)
    {
        long long f1=top[u],f2=top[v];
        while (f1!=f2)
        {
            if (dep[f1]<dep[f2]) {swap(f1,f2);swap(u,v);}
            u=fath[f1];f1=top[u];
        }
        if (dep[u]<dep[v]) return u;
        else return v;
    }
    void work(long long x)
    {
        long long u=e[x].u,v=e[x].v,ret=dis[u]+e[x].w+dis[v];
        long long t=lca(u,v);
        if (t==v) return;
        u=t;
        long long f1=top[u],f2=top[v];
        while (f1!=f2)
        {
            if (dep[f1]<dep[f2]) {swap(f1,f2);swap(u,v);}
            modify(root,1,n,dfn[f1],dfn[u],ret);
            u=fath[f1];f1=top[u];
        }
        if (u!=v)
        {
            if (dep[u]>dep[v]) swap(u,v);
            modify(root,1,n,dfn[u]+1,dfn[v],ret);
        }
    }
    long long ask(long long now,long long left,long long right,long long pos)
    {
        if (left==right)
            return lazy[now];
        long long mid=(left+right)>>1;
        if (pos<=mid) return min(ask(ls[now],left,mid,pos),lazy[now]);
        else return min(ask(rs[now],mid+1,right,pos),lazy[now]);
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for (long long i=1;i<=m;i++)
        {
            scanf("%lld%lld%lld%lld",&x,&y,&a,&b);
            addedge(x,y,a,b);
            addedge(y,x,a,b);
        }
        dfs1(1);
        dfs2(1,1);
        build(root,1,n);
        for (long long i=1;i<=nume;i++)
        {
            long long u=e[i].u,v=e[i].v,ret=dis[u]+e[i].w+dis[v];
            if (e[i].flag) continue;
            work(i);
        }
        for (long long i=2;i<=n;i++)
        {
            long long ret=ask(root,1,n,dfn[i]);
            if (ret==inf) printf("-1 ");
            else printf("%lld ",ret-dis[i]);
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    asp复制到word实现分页效果
    玩转网络MAC地址
    取消开机画面的登录
    C#调用vc的dll.设置参数等
    C++中类的静态数据成员函数解析
    吉林大学vc6.0视频记录
    根据进程号获取程序名
    (转)C#中Split分隔字符串的应用(C#、split、分隔、字符)
    MSSQL表别名使用注意事项
    (转)ArrayList 与 string[] 的转换
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5834596.html
Copyright © 2011-2022 走看看