zoukankan      html  css  js  c++  java
  • USACO09JAN 安全出行Safe Travel

    题目描述

    题解:

    因为这个东西占的是最短路的最后一条边,我们可以建出最短路树。

    一遍dij即可。

    如果这个图就是一棵树,那么所有答案全为-1;

    所以说非树边更新了答案。

    现在让我们开一棵 2,2,4-三甲基-3-乙基戊烷 ,就是#r巨佬的231树。

    如果6- - ->7,那3和7的答案都可以由1->2->6- - ->7->3->1更新。

    如果7- - ->8,那么只有8的答案可被1->3->7- - ->8->3->1更新。

    说白了,如果f- - ->t而且t不是f的祖先,那t到lca(f,t)路径上除了lca的所有点都能被更新。

    树链修改,树剖+线段树。

    最后dp[i]=min(DP[i])-dis[i];

    都表示啥就不说了。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    #define M 200050
    #define ll long long
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,hed[N],cnt=-1;
    struct EG
    {
        int f,t,v,nxt;
        bool use;
    }e[2*M];
    void ae(int f,int t,int v)
    {
        e[++cnt].f = f;
        e[cnt].t = t;
        e[cnt].v = v;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    struct node
    {
        int x;
        ll d;
        node(){}
        node(int x,ll d):x(x),d(d){}
        friend bool operator < (node a,node b)
        {
            return a.d>b.d;
        }
    };
    ll dis[N];
    bool vis[N];
    void dij()
    {
        priority_queue<node>q;
        q.push(node(1,0));
        memset(dis,0x3f,sizeof(dis));
        dis[1]=0;
        while(!q.empty())
        {
            node tp = q.top();
            q.pop();
            int u = tp.x;
            if(vis[u])continue;
            vis[u]=1;
            for(int j=hed[u];~j;j=e[j].nxt)
            {
                int to = e[j].t;
                if(dis[to]>dis[u]+e[j].v)
                {
                    dis[to]=dis[u]+e[j].v;
                    q.push(node(to,dis[to]));
                }
            }
        }
    }
    bool in_tree[N];
    int fa[N];
    void build()
    {
        queue<int>q;
        q.push(1);
        in_tree[1]=1;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int j=hed[u];~j;j=e[j].nxt)
            {
                int to = e[j].t;
                if(in_tree[to]||dis[to]!=dis[u]+e[j].v)continue;
                in_tree[to]=1;
                e[j].use=1;e[j^1].use=1;
                q.push(to);
            }
        }
    }
    int siz[N],top[N],son[N],dep[N];
    void dfs1(int u,int f)
    {
        fa[u]=f;
        dep[u]=dep[f]+1;
        siz[u]=1;
        for(int j=hed[u];~j;j=e[j].nxt)
        {
            int to = e[j].t;
            if(!e[j].use||to==f)continue;
            dep[to]=dep[u]+1;
            dfs1(to,u);
            siz[u]+=siz[to];
            if(siz[to]>siz[son[u]])son[u]=to;
        }
    }
    int tin[N],tim,pla[N];
    void dfs2(int u,int tp)
    {
        top[u]=tp;tin[u]=++tim;pla[tim]=u;
        if(son[u])
        {
            dfs2(son[u],tp);
            for(int j=hed[u];~j;j=e[j].nxt)
            {
                int to = e[j].t;
                if(!e[j].use||to==son[u]||to==fa[u])continue;
                dfs2(to,to);
            }
        }
    }
    int get_lca(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            x=fa[top[x]];
        }
        return dep[x]<dep[y]?x:y;
    }
    const ll inf = 0x3f3f3f3f3f3f3f3fll;
    ll dp[N];
    struct segtree
    {
        ll v[N<<2],tag[N<<2];
        void renew(int u,ll d)
        {
            if(d<v[u])
            {
                v[u]=d;
                tag[u]=d;
            }
        }
        void pushdown(int u)
        {
            if(tag[u]!=inf)
            {
                renew(u<<1,tag[u]);
                renew(u<<1|1,tag[u]);
                tag[u]=inf;
            }
        }
        void build(int l,int r,int u)
        {
            v[u]=tag[u]=inf;
            if(l==r)return ;
            int mid = (l+r)>>1;
            build(l,mid,u<<1);
            build(mid+1,r,u<<1|1);
        }
        void insert(int l,int r,int u,int ql,int qr,ll d)
        {
            if(l==ql&&r==qr)
            {
                renew(u,d);
                return ;
            }
            pushdown(u);
            int mid = (l+r)>>1;
            if(qr<=mid)insert(l,mid,u<<1,ql,qr,d);
            else if(ql>mid)insert(mid+1,r,u<<1|1,ql,qr,d);
            else insert(l,mid,u<<1,ql,mid,d),insert(mid+1,r,u<<1|1,mid+1,qr,d);
        }
        void print(int l,int r,int u)
        {
            if(l==r)
            {
                dp[pla[l]] = v[u]-dis[pla[l]];
                return ;
            }
            pushdown(u);
            int mid = (l+r)>>1;
            print(l,mid,u<<1);
            print(mid+1,r,u<<1|1);
        }
    }tr;
    int main()
    {
        n=rd(),m=rd();
        memset(hed,-1,sizeof(hed));
        for(int f,t,v,i=1;i<=m;i++)
        {
            f=rd(),t=rd(),v=rd();
            ae(f,t,v),ae(t,f,v);
        }
        dij();
        build();
        dfs1(1,0);
        dfs2(1,1);
        tr.build(1,n,1);
        for(int f,t,j=0;j<=cnt;j++)
        {
            if(e[j].use)continue;
            f = e[j].f,t = e[j].t;
            int lca = get_lca(f,t);
            if(lca==t)continue;
            ll tmp = dis[f]+dis[t]+e[j].v;
            int now=top[t];
            while(dep[now]>dep[lca])
            {
                tr.insert(1,n,1,tin[now],tin[t],tmp);
                t = fa[now],now = top[t];
            }
            if(dep[t]>dep[lca])
                tr.insert(1,n,1,tin[lca]+1,tin[t],tmp);
        }
        tr.print(1,n,1);
        for(int i=2;i<=n;i++)
        {
            if(dp[i]>10000000000ll)dp[i]=-1;
            printf("%lld
    ",dp[i]);
        }
        return 0;
    }
  • 相关阅读:
    fastlane 自动化打包不同的target,以及手动传版本号参数
    xcode 添加Account报错 This action could not be completed,Try again
    iOS 如何在模拟器中安装APP
    git 基础总结
    cnpm run build 报错 Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 9.x
    iOS 静态库sdk项目依赖到工程项目测试
    Windows下程序的自删除
    80x86指令码查询表(转载)
    C语言实现Win32第一个窗口
    Visual Studio的Unicode和ASCII
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10155231.html
Copyright © 2011-2022 走看看