链接:HDUOJ2544
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
1.Dijkstra
ac代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define N 100+10
#define inf 0x3f3f3f3f
int main()
{
int n,m;
int a,b,c;
bool vis[N];
int dis[N];
int map[N][N];
while(scanf("%d%d",&n,&m)&&(n+m))
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
map[i][j]=inf;
vis[i]=0;
dis[i]=inf;
}
int temp;
int p;
for(int i=0; i<m; i++)
{
scanf("%d %d %d",&a,&b,&c);
if(c<map[a][b])
map[a][b]=c;
if(c<map[b][a])
map[b][a]=c;
}
dis[1]=0;
vis[1]=1;
for(int i=1; i<=n; i++)
dis[i]=map[1][i];
for(int j=0; j<n; j++)
{
temp=inf;
for(int i=1; i<=n; i++)
{
if((!vis[i])&&(dis[i]<temp))
{
temp=dis[i];
p=i;
}
}//找到dis里未被遍历的最小值
vis[p]=1;//将最小点加入集合
for(int i=1; i<=n; i++)
{
if((!vis[i])&&(map[p][i]+dis[p]<dis[i]))
{
dis[i]=dis[p]+map[p][i];
}
}
}
cout<<dis[n]<<endl;
}
return 0;
}
2.SPFA
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 10000 + 10
#define inf 0x3f3f3f3f
struct node
{
int v;
int len;
int nex;
} e[N];
int cnt;
bool vis[N];
int id[N];
int m,n;
int dis[N];
void add(int from,int to,int len)
{
e[cnt].v=to;
e[cnt].len=len;
e[cnt].nex=id[from];
id[from]=cnt++;
}//链式前向星
int main()
{
int a,b,c;
while(scanf("%d%d",&n,&m)&&(n+m))
{
cnt = 0;
for(int i=1; i<=n; i++)
{
vis[i]=0;
dis[i]=inf;
id[i] = -1;
}
queue<int>q;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
q.push(1);
vis[1]=1;
dis[1]=0;
while(!q.empty())
{
int t = q.front();
q.pop();
//vis[t] = 0;
for(int i = id[t]; ~i; i = e[i].nex)
{
if(dis[e[i].v] > dis[t] + e[i].len)
{
dis[e[i].v] = dis[t] + e[i].len;
if(!vis[e[i].v])
{
q.push(e[i].v);
vis[e[i].v] = 1;
}
}
}
vis[t] = 0;
}
printf("%d\n",dis[n]);
}
return 0;
}
3.Floyd
核心代码
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
}
可以找多源最短路,想知道a点到b点最短路,只能加入中间点来缩短路径,比如a到b 加入中间点k a到k到b