http://acm.hdu.edu.cn/showproblem.php?pid=1385
在未學習Dijkstra記錄路徑之前,對於這道題目,複雜度不大的前提下,我選擇了用Floyd記錄路徑。
pre數組記錄路徑,map爲原圖,兩點之間無路時爲INF.
int pre[vex_num][vex_num],map[vex_num][vex_num];
void Floyd()
{
int i,j,k;
for(i=0;i<vex_num;i++)
{
for(j=0;j<vex_num;j++)
{
if(map[i][j]!=INF)
pre[i][j]=j;//i的後繼元素是j
else
pre[i][j]=-1;
}
}
for(k=0;k<vex_num;k++)
{
for(i=0;i<vex_num;i++)
{
for(j=0;j<vex_num;j++)
{
if(map[i][k]+map[k][j]<map[i][j])
{
map[i][j]=map[i][k]+map[k][j];
pre[i][j]=pre[i][k];
}
else if(map[i][k]+map[k][j]==map[i][j])
{
if(pre[i][j]>pre[i][k])
pre[i][j]=pre[i][k];//pre數組中記錄的是最小的
}
}
}
}
}
HDU 1385這道題目意思很簡單,輸入一張圖,求start到end兩點之間的最短距離並且輸出路徑,當存在多條路徑時,輸出lexically最小的那條路徑。這道題目還有一個地方是:每個地方都有一個權值,這個權值無需加到原圖上。
思路:構圖+Floyd( 記錄路徑的)
貼下代碼:
#include<stdio.h>
#include<string.h>
#define MAXN 100
#define INF 10000000
int map[MAXN][MAXN],path[MAXN][MAXN];
int output[MAXN],B[MAXN];
void Floyd(int n)
{
int i,j,k;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
path[i][j]=j;
}
}
for(k=1;k<=n;k++){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(map[i][k]+map[k][j] + B[k]<map[i][j]){
map[i][j]=map[i][k]+map[k][j] + B[k];
path[i][j]=path[i][k];
}
else if(map[i][k]+map[k][j] + B[k]==map[i][j]){
if(path[i][j]>path[i][k])
path[i][j]=path[i][k];
}
}
}
}
}
int main()
{
int n,i,j,a;
while(scanf("%d",&n)!=EOF&&n){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
scanf("%d",&a);
if(a==-1)
map[i][j]=INF;
else
map[i][j]=a;
}
}//構圖
for(i=1;i<=n;i++)
scanf("%d",&B[i]);
Floyd(n);
int s,e;
while(scanf("%d%d",&s,&e)!=EOF){
if(s==-1&&e==-1)
break;
printf("From %d to %d :/n",s,e);
printf("Path: %d",s);
int tt=s;
while(tt!=e){
printf("-->%d",path[tt][e]);
tt=path[tt][e];
}
printf("/nTotal cost : %d/n/n",map[s][e]);
}
}
return 0;
}