• 【xsy2304】哈 最短路


    题目大意:有一个$n$个点,$m$条有向边的图,有$q$组询问。

    每次询问:从$a$到$b$,经过不超过$c$条边,且依次经过的边边权递增,问最短路为多少,无解输出-1。

    数据范围:$n≤150$,$m≤5000$,$q≤1000$

    我场上并没有去想正解,打了个spfa居然获得$90pts$好成绩。

    首先对于经过不超过$c$条边,当$c>n-1$时,是没有意义的(显然经过边数不会超过$n-1$),这种情况下我们直接将$c$赋值为$n-1$即可。

    我们设$dis[i][j]$表示从$a$出发,经过不超过j条边后到达i的最短距离。

    答案显然为$minlimits_{i=1}^{c}dis[b][i]$。

    考虑如何满足要求的边权递增:我们显然只需要把这些边从小到大排个序,然后从小到大拿出,丢去增广即可。

    单次查询的复杂度显然是$O(mc)$的,上限显然是$O(nm)$。

    那么,总时间复杂度为$O(mlog m+qnm)$。

     1 #include<bits/stdc++.h>
     2 #define N 155
     3 #define M 5005
     4 #define INF 16843009
     5 using namespace std;
     6 
     7 struct edge{
     8     int u,v,w;
     9     void rd(){scanf("%d%d%d",&u,&v,&w);}
    10     friend bool operator <(edge a,edge b){return a.w<b.w;}
    11 }a[M];
    12 int n,m,Q;
    13 
    14 int dis[N][N]={0};
    15 void spfa(int A,int b,int c){
    16     memset(dis,1,sizeof(dis));
    17     dis[A][0]=0;
    18     c=min(c,n);
    19     for(int i=1;i<=m;i++){
    20         for(int j=1;j<=c;j++)
    21         dis[a[i].v][j]=min(dis[a[i].v][j],dis[a[i].u][j-1]+a[i].w);
    22     }
    23     int minn=INF;
    24     for(int i=0;i<=c;i++) minn=min(minn,dis[b][i]);
    25     if(minn==INF) minn=-1;
    26     printf("%d
    ",minn);
    27 }
    28 
    29 int main(){
    30     scanf("%d%d%d",&n,&m,&Q);
    31     for(int i=1;i<=m;i++) a[i].rd();
    32     sort(a+1,a+m+1);
    33     while(Q){
    34         int a,b,c; scanf("%d%d%d",&a,&b,&c);
    35         spfa(a,b,c);
    36         Q--;
    37     }
    38 }
  • 相关阅读:
    Nginx log日志参数详解
    sea.js模块加载工具
    sea.js模块加载工具
    Airbnb React/JSX 编码规范
    4.2 react patterns(转)
    4.1 react 代码规范
    3.5 compose redux sages
    3.3 理解 Redux 中间件(转)
    3.4 redux 异步
    3.1 开始使用 redux
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10777587.html
Copyright © 2020-2023  润新知