zoukankan      html  css  js  c++  java
  • [bzoj1726] Roadblocks

    1726: [Usaco2006 Nov]Roadblocks第二短路

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1578  Solved: 795
    [Submit][Status][Discuss]

    Description

    贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。

    Input

    * 第1行: 两个整数,N和R,用空格隔开

    * 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B

    Output

    * 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度

    Sample Input

    4 4
    1 2 100
    2 4 200
    2 3 250
    3 4 100

    Sample Output

    450

    输出说明:

    最短路:1 -> 2 -> 4 (长度为100+200=300)
    第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)

    HINT 

    Source

    Gold

    题意:

    求无向图中$1 ightarrow N$的严格次短路长度。

    题解:

    树上次长链都会维护了,图上次短路怎么能不会……

    考虑常用的$Dijkstra$的运行过程,每次从优先队列队首挑一个$dis$最小的点,该点的$dis$就被确定下来(都是正权边一定没有再能更新他的边)。

    然后通过该点松弛与之相连的其他点并把它们扔到优先队列中。扔到$N$即可退出。

    那么次短路同理,在优先队列中出现的第一个不等于该点最短路的次短路一定是唯一确定的(没有再能更新他的最短路或次短路)。

    于是只需要记录该点最短路和次短路是否出现过,并在往优先队列里push的时候标记上这是最短路还是次短路即可。

    注意最短路若被更新,次短路要继承最短路的值。

    代码:(md我优先队列排序排反还在bzoj上$A$了是什么操作啊)

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
     
    using namespace std;
    #define MAXN 100005
    #define MAXM 500005
    #define INF 0x7fffffff
    #define ll long long
     
    struct node{
        int u,d,c;
        bool operator<(const node b)const{
            return d>b.d;
        } 
    };
    int hd[MAXN],to[MAXM<<1];
    int nxt[MAXM<<1],cst[MAXM<<1];
    int N,M,cnt,dis[MAXN][2];
    bool vis[MAXN][2];
     
    inline int read(){
        int x=0,f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar())
            if(c=='-')
                f=-1;
        for(;isdigit(c);c=getchar())
            x=x*10+c-'0';
        return x*f;
    }
     
    inline void addedge(int u,int v,int w){
        to[++cnt]=v,cst[cnt]=w;
        nxt[cnt]=hd[u],hd[u]=cnt;
        return;
    }
     
    inline int Dijkstra(int s){
        memset(dis,63,sizeof(dis));
        memset(vis,0,sizeof(vis));
        priority_queue<node> q;
        q.push({1,0,0});
        dis[1][0]=0;
        while(!q.empty()){
            node h=q.top();q.pop();
            if(vis[h.u][h.c]) continue;
            vis[h.u][h.c]=1;
            for(int i=hd[h.u];i;i=nxt[i]){
                int u=h.u,v=to[i],w=cst[i];
                if(dis[v][0]>h.d+w){
                    dis[v][1]=dis[v][0];
                    dis[v][0]=h.d+w;
                    q.push(node{v,dis[v][0],0});
                    q.push(node{v,dis[v][1],1});
                }
                if(dis[v][1]>h.d+w && h.d+w!=dis[v][0]){
                    dis[v][1]=h.d+w;
                    q.push(node{v,dis[v][1],1});
                }
            }
        }
        return dis[N][1];
    }
     
    int main(){
        N=read(),M=read();
        for(int i=1;i<=M;i++){
            int u=read(),v=read(),w=read();
            addedge(u,v,w);addedge(v,u,w);
        }
        printf("%d
    ",Dijkstra(1));
        return 0;
    }
  • 相关阅读:
    Xml---->JAXP DOM解析
    java(web)相对路径,绝对路径
    重定向与转发
    struts2之限制文件上传类型
    Struts2之文件上传上限
    Struts2之result中标准结果代码
    struts2之指定处理的请求后缀
    File.rename操作后,获取文件的名称,输出的名称仍为之前的名称
    硬盤掛載
    Java应用打包后运行需要注意编码问题 .
  • 原文地址:https://www.cnblogs.com/YSFAC/p/9879044.html
Copyright © 2011-2022 走看看