zoukankan      html  css  js  c++  java
  • bzoj 1576: [Usaco2009 Jan]安全路经Travel——并查集+dijkstra

    Description

    Input

    * 第一行: 两个空格分开的数, N和M

    * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i

    Output

    * 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.

    如果这样的路经不存在,输出-1.

    Sample Input

    4 5
    1 2 2
    1 3 2
    3 4 4
    3 2 1
    2 4 3

    Sample Output

    3
    3
    6
    —————————————————————————————————
    由于最短路唯一,先求最短路径树,考虑非树边uv,它能使uv以上,lca以下的点多一种路径,长度为dis[u] + dis[v] + edge[i] - dis[x]。
    因为dis[x]是常数 我们令这条非树边的值为val[i] = dis[u] + dis[v] + edge[i],我们只需对每个x,找出最小的val。
    可以先按val排序,然后使用并查集压缩路径即可。
    因为已经赋值过的点一定比现在解更优 所以防止多次算到一个点 我们可以把他们合并起来一起跳过
    这道题不能写spfa会被卡QAQ dj快很多 spfa佳slf优化也很慢 勉强能过
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=1e5+7,M=4e5+7,inf=0x3f3f3f3f;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,m,ans[N];
    int f[N],fa[N];
    int find(int x){while(x!=f[x]) x=f[x]=f[f[x]]; return x;}
    int first[N],cnt,cntq;
    struct node{int from,to,next,w;}e[M],qs[M];
    bool cmp(node a,node b){return a.w<b.w;}
    void ins(int a,int b,int w){e[++cnt]=(node){a,b,first[a],w}; first[a]=cnt;}
    void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
    int dis[N],dep[N];
    struct Q{
        int d,pos;
        bool operator <(const Q& x)const{return x.d<d;}
    };
    priority_queue<Q>q;
    void dj(){
        memset(dis,0x3f,sizeof(dis));
        q.push((Q){0,1}); dis[1]=0;
        while(!q.empty()){
            Q p=q.top(); q.pop();
            if(p.d>dis[p.pos]) continue;
            int x=p.pos;
            for(int i=first[x];i;i=e[i].next){
                int now=e[i].to;
                if(dis[now]>dis[x]+e[i].w){
                    dis[now]=dis[x]+e[i].w;
                    dep[now]=dep[x]+1;
                    fa[now]=x;
                    q.push((Q){dis[now],now});
                }
            }
        }
    }
    int main(){
        int x,y,w;
        n=read(); m=read();
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w);
        dj();
        for(int i=1;i<=cnt;i++){
            x=e[i].from; y=e[i].to;
            if(dep[x]<dep[y]) swap(x,y);
            if(dis[x]==dis[y]+e[i].w) continue;
            qs[++cntq]=(node){x,y,0,dis[x]+dis[y]+e[i].w};
        }
        sort(qs+1,qs+1+cntq,cmp);
        for(int i=1;i<=cntq;i++){
            x=qs[i].from; y=qs[i].to;
            while(x!=y){
                if(dep[x]<dep[y]) swap(x,y);
                if(!ans[x]) ans[x]=qs[i].w-dis[x];
                x=f[x]=find(fa[x]); //printf("[%d]
    ",x);
            }
        }    
        for(int i=2;i<=n;i++){
            if(!ans[i]) printf("-1
    ");
            else printf("%d
    ",ans[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    默认Web字体样式
    从Reddit学到的七条经验
    Git魔法 前言
    26个提升java性能需要注意的地方
    解密Redis持久化
    离开Java,寻找更佳语言的10大理由
    » DebBuilder V2.2.2 测试版发布 Wow! Ubuntu
    YaCy 1.0 发布,自由软件搜索引擎
    Socket 短连接、长连接_YTmarkit的空间_百度空间
    TopHQBooks – PDF 搜索引擎 小众软件
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7441298.html
Copyright © 2011-2022 走看看