最短路 HDU杭电2544【dijkstra算法 || SPFA】

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
 


//Dijkstra

  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #define INF 0x3f3f3f3f  
  4. int map[110][110];  
  5. int dis[11000];  
  6. bool used[11000];  
  7. int n;  
  8. int i,j;  
  9. void dijkstra(int u)  
  10. {  
  11.     memset(used,0,sizeof(used));  
  12.     memset(dis,INF,sizeof(dis));  
  13.     int pos=u;  
  14.     for(i=1;i<=n;++i)//第一次给dis赋值   
  15.     {  
  16.         dis[i]=map[u][i];  
  17.     }  
  18.     dis[u]=0;  
  19.     used[u]=1;  
  20.     for(i=1;i<n;++i)//再找n-1个点   
  21.     {  
  22.         int min=INF;  
  23.         for(j=1;j<=n;++j)  
  24.         {  
  25.             if(!used[j]&&dis[j]<min)  
  26.             {  
  27.                 min=dis[j];  
  28.                 pos=j;  
  29.             }  
  30.         }   
  31.         used[pos]=1;  
  32.         dis[pos]=min;  
  33.         for(j=1;j<=n;++j)//把dis数组更新,也叫松弛  
  34.         {  
  35.             if(!used[j]&&dis[j]>map[pos][j]+dis[pos])  
  36.             {  
  37.                 dis[j]=map[pos][j]+dis[pos];  
  38.             }  
  39.         }  
  40.     }  
  41.   
  42. }  
  43. int main()  
  44. {  
  45.     int m;  
  46.     int u,v,w;  
  47.     while(~scanf("%d%d",&n,&m),m+n)  
  48.     {         
  49.         for(i=1;i<=n;++i)  
  50.             for(j=1;j<=n;++j)  
  51.                 map[i][j]=INF;  
  52.         while(m--)  
  53.         {  
  54.             scanf("%d%d%d",&u,&v,&w);  
  55.             if(map[u][v]>w)  
  56.                 map[u][v]=map[v][u]=w;  
  57.         }  
  58.         dijkstra(1);  
  59.         printf("%d\n",dis[n]);  
  60.     }  
  61.     return 0;  
  62. }  

//SPFA

//两道题都没注意这是无向边

  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <queue>  
  4. #define MAXN 110  
  5. #define MAXM 10100  
  6. #define INF 0x3f3f3f3f  
  7. using namespace std;  
  8. struct Edge  
  9. {  
  10.     int u, v, w;  
  11.     int next;//下一个结构体变量的下标   
  12. }edge[MAXM];  
  13. int head[MAXM];//下标为起点u,值为对应结构体下标   
  14. int vis[MAXN];//判断是否加入队列了   
  15. int M, N;  
  16. int num;  
  17. int low[MAXN];//存最短路径   
  18. void Add_Edge(int u, int v, int w)//加边   
  19. {  
  20.     Edge E={u, v, w, head[u]};//初始化结构体   
  21.     edge[num]=E;//直接赋值   
  22.     head[u]=num++;  
  23. }  
  24. void SPFA(int s)  
  25. {  
  26.     int i, j;  
  27.     queue<int> Q;  
  28.     memset(low, INF, sizeof(low));   
  29.     memset(vis, 0, sizeof(vis));      
  30.     vis[s] = 1;  
  31.     low[s]=0;   
  32.     Q.push(s);  
  33.     while(!Q.empty())  
  34.     {  
  35.         int u=Q.front();  
  36.         Q.pop();  
  37.         vis[u]=0;//出队列了,不在队列就变成0   
  38.         for(j = head[u]; j != -1; j = edge[j].next)  
  39.         {  
  40.             int v = edge[j].v;  
  41.             if(low[v] > low[u] + edge[j].w)  
  42.             {  
  43.                 low[v] = low[u] + edge[j].w;  
  44.                 if(!vis[v] )                   
  45.                 {  
  46.                     vis[v]=1;  
  47.                     Q.push(v);  
  48.                 }  
  49.             }  
  50.         }  
  51.     }  
  52.     printf("%d\n",low[N]);  
  53. }  
  54. int main()  
  55. {  
  56.     int u, v, w;  
  57.     while(~scanf("%d%d", &N, &M), N|M)  
  58.     {  
  59.         memset(head, -1, sizeof(head));  
  60.         num=0;  
  61.         while(M--)  
  62.         {  
  63.             scanf("%d%d%d", &u, &v, &w);  
  64.             Add_Edge(u, v, w);  
  65.             Add_Edge(v, u, w);//无向边   
  66.         }         
  67.         SPFA(1);  
  68.     }  
  69.     return 0;  
  70. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值