【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

 

posted @ 2017-11-09 22:46  Cxsheng  阅读(177)  评论(0编辑  收藏  举报