zoukankan      html  css  js  c++  java
  • JZOJ 5279 香港记者

    一句话题意:一个带点权边权的无向图,输出从1号点到n号点的最短路中字典序最小的一条路径

    样例输入:

    8 9
    1 2 3 4 5 6 7 8
    1 2 2
    2 3 3
    3 8 3
    1 4 3
    4 5 2
    5 8 1
    1 6 1
    6 7 2
    7 8 3

    样例输出:

    6
    1 4 5 8

    思路:

    跑一边spfa(单源最快),更新条件改成(当前路径更短 or (当前路径和原路径相等 and 当前路径字典序更小)),直接开一个pre数组维护当前点的前继就好。

    建议自己写队列,实现只要两分钟(因为代码短),而且不会被卡STL(实际上也没什么变态出题人会去卡一个queue),习惯第一。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<vector>
     7 #define ll long long
     8 using namespace std;
     9 struct edge{
    10     int next,to,w;
    11     edge(){
    12         to=w=0;next=-1;
    13     }
    14 }a[400100];
    15 int n,m,first[200100],bk[200100];
    16 ll dis[200100];bool vis[200100];
    17 ll pre[200100];
    18 struct Queue{
    19     int q[300100],head,tail;
    20     Queue(int k){
    21         head=100000;tail=100001;memset(q,0,sizeof(q));
    22         q[head]=k;
    23     }
    24     void push(int k){
    25         if(dis[k]>dis[q[head]]) q[tail++]=k;
    26         else q[--head]=k;
    27     }
    28     void pop(){
    29         q[head++]=0;
    30     }
    31     int top(){
    32         return q[head];
    33     }
    34     bool empty(){
    35         return (head==tail);
    36     }
    37 };
    38 void spfa(){
    39     Queue q(n);
    40     vis[n]=1;dis[n]=0;pre[n]=n;
    41     int u,v,w,i;
    42     while(!q.empty()){
    43         u=q.top();q.pop();vis[u]=0;
    44         for(i=first[u];~i;i=a[i].next){
    45             v=a[i].to;w=a[i].w;
    46             if(dis[v]>dis[u]+w||(dis[v]==dis[u]+w&&bk[pre[v]]>=bk[u])){
    47                 dis[v]=dis[u]+w;
    48                 pre[v]=u;
    49                 if(!vis[v]){
    50                     vis[v]=1;q.push(v);
    51                 }
    52             }
    53         }
    54     }
    55 }
    56 int main(){
    57     scanf("%d%d",&n,&m);
    58     for(int i=1;i<=n;i++){
    59         first[i]=-1;dis[i]=0x3f3f3f3f3f3f3f;
    60         scanf("%d",&bk[i]);
    61     }
    62     int t1,t2,t3;
    63     for(int i=1;i<=m;i++){
    64         scanf("%d%d%d",&t1,&t2,&t3);
    65         a[i].to=t1;a[i].next=first[t2];a[i].w=t3;first[t2]=i;
    66     }
    67     spfa();
    68     printf("%lld
    %d ",dis[1],bk[1]);
    69     int i=1;
    70     while(i!=n){
    71         printf("%d ",bk[pre[i]]);i=pre[i];
    72     }
    73 }
  • 相关阅读:
    ElasticSearch基础之批量操作(mget+mbulk)
    ElasticSearch基础+文档CRUD操作
    Flask_restful 插件实战笔记——基本概念与使用
    Django rest framework之序列化小结
    我所理解的Restful API最佳实践
    ElasticSearch入门及核心概念介绍
    生产环境下Flask项目目录构建
    利用linq的Take Skip方法解决 集合拆分的问题
    Oracle trunc() 函数处理数字、日期的整理
    左连接条件与where条件的区别
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/7445564.html
Copyright © 2011-2022 走看看