最短路

来源:互联网 发布:elfgame软件视频格式 编辑:程序博客网 时间:2024/06/07 07:54

最短路

Time Limit : 5000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 30   Accepted Submission(s) : 25
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 11 2 33 31 2 52 3 53 1 20 0
 

Sample Output
32
 
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define Max 10000000int n, m;int map[105][105];int d[105], d1[105];void Dijkstra(){memset(d, 0, sizeof(d));memset(d1, 0, sizeof(d1));for (int i = 1; i <= n; i++)d1[i] = map[i][1];d[1] = 1;for (int i = 1; i <= n; i++){int maxc = Max, c = 0;for (int j = 1; j <= n; j++)if (!d[j] && d1[j] < maxc)  maxc = d1[j], c = j; d[c] = 1; if (c == 0 || c == n) return;for (int k = 1; k <= n; k++) if (!d[k] && d1[k]>d1[c] + map[k][c])d1[k] = d1[c] + map[k][c];}}int main(){while (scanf("%d%d", &n, &m), (n + m)){for (int i = 1; i <= n;i++)for (int j = i; j <= n; j++){map[i][j] = map[j][i] = Max;if (i == j) map[i][j] = map[j][i] = 0;}for (int i = 0; i < m; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);if (map[a][b]>c) map[a][b] = map[b][a] = c;}Dijkstra();printf("%d\n", d1[n]);}return 0;}


SPFA 算法最短路径  前向星  制图

#include <iostream>#include<stdio.h>#include<string.h>#include<string>#include<cmath>#include<queue>#include<algorithm>using namespace std;#define Maxn 10000   /// 顶点数#define Max 10000000 ///int used[Maxn];      /// 标记是否在队列中int head[Maxn];      /// 顶点int low[Maxn];       /// 记录最短路径int outqueue[Maxn];  /// 记录同一顶点入队过多少次(即更新过多少次)int n,m,cou; /// 顶点数 边数struct Edge{    int to,w,next;} edge[Max];void add(int a,int b,int w){    edge[cou].to=b;    edge[cou].w=w;    edge[cou].next=head[a];    head[a]=cou++;}bool SPFA(int x){    queue<int>Q;    used[x]=1;  /// 用来标记是否入队    low[x]=0;   /// 记录最后的答案    Q.push(x);    while(!Q.empty())    {        int top=Q.front();        Q.pop();        used[top]=0;        outqueue[top]++;    ///  出队次数 (即更改次数)  超过定点数者存在 负权环        if(outqueue[top]>n) return false;        for(int i=head[top]; i!=-1; i=edge[i].next) /// 把所有以 top  为顶点边都访问一遍        {            if(low[edge[i].to]>low[top]+edge[i].w)  ///当松弛操作成功和队中没有该顶点时入队            {                low[edge[i].to]=low[top]+edge[i].w;                if(!used[edge[i].to])                {                    Q.push(edge[i].to);                    used[edge[i].to]=1; /// 标记已加入了队中                }            }        }    }    return true;}int main(){    while(scanf("%d%d",&n,&m),(n+m))    {        memset(used,0,sizeof(used));        memset(head,-1,sizeof(head));        memset(outqueue,0,sizeof(outqueue));        fill(low,low+Maxn,Max);        int a,b,w;        cou=0;        for(int i=0; i<m; i++)        {            scanf("%d%d%d",&a,&b,&w);            add(a,b,w);  /// 双向图            add(b,a,w);        }        if(SPFA(1))            printf("%d\n",low[n]);        else            printf("不存在!\n");    }    return 0;}



0 0