SDUT 2143 圖結構練習——最短路徑
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
給定一個帶權無向圖,求節點1到節點n的最短路徑。
Input
輸入包含多組數據,格式如下。
第一行包括兩個整數n m,代表節點個數和邊的個數。(n<=100)
剩下m行每行3個正整數a b c,代表節點a和節點b之間有一條邊,權值爲c。
Output
每組輸出佔一行,僅輸出從1到n的最短路徑權值。(保證最短路徑存在)
Example Input
3 2
1 2 1
1 3 1
1 0
Example Output
1
0
Hint
本題用到了Dijkstra算法:
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
Submit
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;//表示無窮大
const int MAXN = 110;
int N, M;
int mp[MAXN][MAXN];
int dist[MAXN];//distance,記錄距離
bool visit[MAXN];//記錄點是否被訪問過
void dijkstra()
{
int i, j, k;
memset(visit, 0, sizeof(visit));
visit[1] = 1;
for(i = 1; i <= N; i++)//初始化中間點爲點1
{
dist[i] = mp[1][i];
}
for(i = 2; i <= N; i++)//中間點一共移動次數
{
int Min = INF;
for(j = 1; j <= N; j++)//找出中間點
{
if(!visit[j] && dist[j] < Min)
{
Min = dist[j];
k = j;//點k爲未訪問過的離點1距離最短的點,即爲中間點
}
}
visit[k] = 1;
for(j = 1; j <= N; j++)//當找到更短距離時替換原先路徑距離
if(!visit[j] && mp[k][j] != INF)//保證路徑存在且未訪問過
if(dist[j] > dist[k] + mp[k][j])
dist[j] = dist[k] + mp[k][j];//替換
}
printf("%d\n",dist[N]);
}
int main()
{
while(~scanf("%d %d", &N, &M))
{
memset(mp, INF, sizeof(mp));//初始化爲無窮
int i;
int a, b, c;
for(i = 1; i <= N; i++)//每個點到自身距離爲0
mp[i][i] = 0;
for(i = 1; i <= M; i++)
{
scanf("%d %d %d", &a, &b, &c);
mp[a][b] = mp[b][a] = c < mp[a][b] ? c : mp[a][b];//mp[a][b]爲兩點間存在的最短距離
}
dijkstra();
}
return 0;
}