【20171109】Luogu P3371 【模板】单源最短路径--SPFA

题目描述

如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

输入输出格式

输入格式:

第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

输出格式:

一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

输入输出样例

输入样例#1:复制

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

输出样例#1:复制

0 2 4 3

说明

时空限制:1000ms,128M

数据规模:

对于20%的数据:N<=5,M<=15

对于40%的数据:N<=100,M<=10000

对于70%的数据:N<=1000,M<=100000

对于100%的数据:N<=10000,M<=500000

花了我一整个晚自习qwq,全赖我不争气的脑子,理解原理用了好久qwq

  1 //begin at 21:04
  2 #include<stdlib.h>
  3 #include <stdio.h>
  4 #define INF 2147483647
  5 #define maxn 10000
  6 #define maxe 500000
  7 typedef struct _edges
  8 {
  9     int w,t;//weight,tailNode
 10     struct _edges *next;
 11 }_edges;
 12 int nv,ne,ibegin;
 13 int minDis[maxn+1];//from [1] to [n]
 14 _edges *edge[maxn+1];//from [1] to [n]
 15 void readG()
 16 {
 17     scanf("%d%d%d",&nv,&ne,&ibegin);
 18     int i,x,y,w;
 19     _edges *p;
 20     for(i=1;i<=nv;i++)
 21     {
 22         edge[i]=NULL;
 23         minDis[i]=INF;
 24     }
 25     for(i=0;i<ne;i++)
 26     {
 27         scanf("%d%d%d",&x,&y,&w);
 28         p=(_edges *)malloc(sizeof(_edges));
 29         p->w=w;
 30         p->t=y;
 31         p->next=edge[x];
 32         edge[x]=p;
 33     }
 34     return;
 35 }
 36 /*void tPrint(int input,char commmand)
 37 {
 38     if (commmand==‘w‘)
 39         printf("%d out\n",input);
 40     else if(commmand==‘r‘)
 41         printf("%d in\n",input);
 42     else if(commmand==‘a‘)
 43     {
 44         int i;
 45
 46     }
 47     return ;
 48 }*/
 49 void SPFA(int begin)
 50 {
 51     int queue[maxn+1];
 52     int isInQueue[maxn+1];
 53     int head,tail;
 54     _edges *p;
 55     int i,h;
 56
 57     for(i=1;i<=nv;i++)
 58         isInQueue[i]=0;
 59     head=0;
 60     queue[0]=begin;
 61     isInQueue[begin]=1;
 62     tail=1;
 63     minDis[begin]=0;
 64     while(head!=tail)
 65     {
 66         h=queue[head%maxn];
 67         //tPrint(h,‘w‘);//==========================
 68         p=edge[h];
 69         isInQueue[h]=0;
 70         while(p!=NULL)
 71         {
 72             if(minDis[h] + p->w < minDis[p->t])
 73             //<==> if(dis[begin][h]+dis[h][t] < dis[begin][t])
 74             {
 75                 minDis[p->t]=minDis[h] + p->w;
 76                 if(isInQueue[p->t]==0)
 77                 {
 78                     isInQueue[p->t]=1;
 79                     queue[(tail++)%maxn]=p->t;
 80                     //tPrint(p->t,‘r‘);//==========================
 81                 }
 82             }
 83             p=p->next;
 84         }
 85         head++;
 86     }
 87     return ;
 88 }
 89 void print()
 90 {
 91     int i;
 92     for(i=1;i<=nv;i++)
 93         printf("%d ",minDis[i]);
 94     printf("\n");
 95 }
 96 int main()
 97 {
 98     readG();
 99     SPFA(ibegin);
100     print();
101     return 0;
102 }
103 //end at 22:42
104 //I used lots of time to catch on the theory
时间: 2024-08-05 14:13:08

【20171109】Luogu P3371 【模板】单源最短路径--SPFA的相关文章

luogu P3371 &amp; P4779 ---单源最短路径spfa &amp; 最大堆优化Dijkstra

P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三个整数Fi.Gi.Wi,分别表示第i条有向边的出发点.目标点和长度. 输出格式: 一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i

[模板]洛谷T3371 单源最短路径 SPFA+手工队列类

一年之后又重新学习此算法...233... 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<ctime> 6 #include<cstdlib> 7 8 #include<string> 9 #include<stack> 10 //#include<queue> 11

【洛谷 p3371】模板-单源最短路径(图论)

题目:给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 解法:spfa算法. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 typedef long long LL; 8 9 const int N=10010,M=500010; 10 c

[模板]单源最短路径

https://www.luogu.org/problemnew/show/P3371 1 #include <cstring> 2 #include <cstdio> 3 #include <iostream> 4 #include <queue> 5 #define lop(i,a,b) for(register int i=a;i<=b;++i) 6 const int N = 10010, M = 500010, inf = 214748364

[模板]单源最短路径(Dijkstra)

如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 主要还是再打一遍最短路,这种算法我用的不多... 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 inline int read() 5 { int x=0;bool f=0;char ch=getchar(); 6 while(!isdigit(ch)){ f=(ch==45);ch=getchar();} 7 while(is

P3371 【模板】单源最短路径 如题

P3371 [模板]单源最短路径 时空限制1s / 128MB 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三个整数Fi.Gi.Wi,分别表示第i条有向边的出发点.目标点和长度. 输出格式: 一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为214

Luogu 3371【模板】单源最短路径

Luogu 3371[模板]单源最短路径 第一次写博客用图论题来试一试 接下来是正文部分 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三个整数Fi.Gi.Wi,分别表示第i条有向边的出发点.目标点和长度. 输出格式: 一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度 (若S=i则最短路径长度为0,若从点S无法到达

P3371 【模板】单源最短路径(弱化版)

P3371 [模板]单源最短路径(弱化版) 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 10005; 4 struct edge { 5 int v, w; 6 }; 7 vector<edge> maps[maxn]; 8 int dis[maxn]; 9 bool vis[maxn]; 10 int n, m, s; 11 void add(int u, int v, int w) {

单源最短路径Dijkstra、BellmanFord、SPFA【模板】

Dijkstra算法: 将所有点分为两个集合.如果源点s到u的最短路径已经确定,点u就属于集合Va,否则属于集合Vb. 1.将源点s到图中各点的直接距离当做初始值记录为s到各点的最短距离,不能到达的记为INF.S到S距离为0. 2.在集合Vb中的点中找一个点u,使得源点s到该点u路径长度最短,将u从Vb中除去,加到V1中.这时候求出了当前S到u的最短路径. 3.把新确定的点u更新s到集合Vb中每一个点v的距离,如果s到u的距离加上u到v的直接距离小于当前s到v的距离,则表示新找到的最短路径长度比