題目鏈接:http://poj.org/problem?id=1502
1.用鄰接矩陣存圖
2.定義mm[u][v]數組表示從u到v的路徑長度,設置一個很大的值表示正無窮
3.維護dis[i]數組 表示源點1到點i的最短路徑長度,初始化值爲mm[1][i]
4.定義book[i]數組標記從1到i的最短路徑長度是否已經確定
Dijkstra算法基本步驟:
1.將所有頂點分爲兩部分,最短路徑長度已知,最短路徑長度未知。
分別用book[i] = 1,book[i]= 0表示
最開始,只有book[1] = 1(源點)
2 .設置dis[1] = 0,若存在源點1能直接到達的點i,則設置dis[i]= mm[1][i],然後把剩下的頂點的最短路徑設爲正無窮
3.在book[i] = 0的所有頂點中找出離源點1最近的頂點u,即dis[u] 最小,然後對u的每一條出邊進行鬆弛操作。然後設置book[u] = 1
例如,有一條從u到v的邊,那麼從源點到v的路徑就有:1–>u–>v
dis[v] = min(dis[v],dis[u]+mm[u][v])
4.重複第3步,直到源點到每個頂點的最短路徑都確定。
這個算法複雜度是O(N^2)
#include <iostream>
#include <cstdio>
using namespace std;
int mm[105][105];
int x = 99999999,dis[105],book[105]; //dis--1號頂點到其他頂點最短路程
int main()
{
int n;
cin>>n;
for (int i = 1; i <= n; i++)
{
mm[i][i] = 0;
}
for (int i = 2; i <= n; i++)
{
for (int j =1; j < i; j++)
{
char temp[10];
int num= 0;
cin>>temp;
if (temp[0] == 'x')
{
mm[i][j] = x;
mm[j][i] = x;
}
else
{
sscanf(temp,"%d",&num);//sscanf表示從字符串中格式化輸入,num爲整型的temp
mm[i][j] = num;
mm[j][i] = num;
}
}
}
for (int i =1; i <= n; i++)
dis[i] = mm[1][i];
for (int i = 1; i <= n; i++)
book[i] = 0;
book[1] = 1;
for (int i =1; i <= n-1; i++)
{
int min = x,t = 1;
// 找到離源點最近的點
for (int j = 1; j <= n; j++)
{
if (book[j] == 0 && dis[j] < min)
{
min = dis[j];
t = j;
}
}
book[t] = 1;
// 鬆弛
for (int v = 1; v <= n; v++)
{
if (mm[t][v] < x && dis[v] > dis[t]+mm[t][v])
{
dis[v] =dis[t]+mm[t][v];
}
}
}
int max = 0;
for (int i = 1;i <= n; i++)
{
if (dis[i] > max)
{
max = dis[i];
}
}
cout<<max<<endl;
return 0;
}