• 最短路(spfa)


    http://acm.hdu.edu.cn/showproblem.php?pid=2544

    最短路

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 41979    Accepted Submission(s): 18360


    Problem Description
    在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

     


    Input
    输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
    输入保证至少存在1条商店到赛场的路线。
     


    Output
    对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
     


    Sample Input
    2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
     


    Sample Output
    3 2
     


    Source
     
    联系spfa模板 
    复杂度O(ke);
    spfa是 bellman-Ford的优化,其用队列解决问题,可以判定负环,每次从队列中出栈一个元素,用这个元素更新其他的点到初始点的距离,被更新的点获得了新的更新别的点的潜力,所以将其也加入到队列中,每次更新dis数组
    如果是用数组来储存队列的时候因为每次i和top 指针都是向后会浪费很多的空间,所以可以使用循环队列,只用开N这么大的数即可,top每次%N ,当i!=top的时候说明队列不空,下面的代码将循环队列的内容给出了特别的标注
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 #define N 250
     6 #define M 10005
     7 #define INF 0x1fffffff
     8 struct Edge{
     9     int to;
    10     int w ;
    11     int next;
    12 }edge[M];
    13 int Enct;
    14 int head[N];
    15 void init()
    16 {
    17     Enct = 0;
    18     memset(head,-1,sizeof(head));
    19 }
    20 void add(int from , int to,int w)
    21 {
    22     edge[Enct].to= to;
    23     edge[Enct].w = w;
    24     edge[Enct].next = head[from];
    25     head[from] = Enct++;
    26     edge[Enct].to= from;
    27     edge[Enct].w = w;
    28     edge[Enct].next = head[to];
    29     head[to] = Enct++;
    30 }
    31 int que[N];
    32 bool inq[N];
    33 int top;
    34 int dis[N];
    35 int n; 
    36 int SPFA()
    37 {
    38     memset(inq,0,sizeof(inq));
    39     for(int i =0 ;i <= n ;i++)
    40         dis[i] = INF;
    41     top = 0;
    42     dis[1] = 0;
    43     que[top++] = 1;
    44     inq[1]=true;
    45     for(int i = 0;i != top ;i = i+1%N)//队列不为空,注意i和top不是同时循环到下一次的
    46     {
    47         int u = que[i];
    48         inq[u]=false;
    49         for(int j = head[u] ; j!=-1 ;j = edge[j].next)
    50         {
    51             Edge e = edge[j];
    52             if(dis[e.to]>dis[u]+e.w)
    53             {
    54                 dis[e.to] = dis[u]+e.w;
    55                 if(inq[e.to]==false)
    56                 {
    57                     que[top++] = e.to;
    58                     top %= N;//循环队列
    59                     inq[e.to] = true;
    60                 }
    61             }
    62         }
    63     }
    64     return dis[n];
    65 }
    66 int main()
    67 {
    68     int m ;
    69     while(~scanf("%d %d",&n,&m) && (n!=0||m!=0))
    70     {
    71         init();
    72         int s , t , w;
    73         for(int i = 0 ;i < m ;i++)
    74         {
    75             scanf("%d%d%d",&s,&t,&w);
    76             add(s,t,w);
    77         }
    78         printf("%d
    ",SPFA());
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    Daily Scrumming 2015.10.20(Day 1)
    Buaaclubs项目介绍
    [转载] Linux创建用户后,切换用户报This account is currently not available
    NetFPGA-1G-CML从零开始环境配置
    Digilent Xilinx USB Jtag cable
    OVS流表table之间的跳转
    Linux换源
    Scapy安装以及简单使用
    Do in SDN
    KMP算法
  • 原文地址:https://www.cnblogs.com/shanyr/p/4707253.html
Copyright © 2020-2023  润新知