這個題有一個小小的tricky,就是要考慮重邊的情況,如果遇到重復的邊,則直接取最小的邊。
Dijkstra(迪傑斯特拉)算法是典型的最短路徑路由算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。Dijkstra算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。其基本思想是,設置頂點集合S並不斷地作貪心選擇來擴充這個集合。一個頂點屬於集合S當且僅當從源到該頂點的最短路徑長度已知。
初始時,S中僅含有源。設u是G的某一個頂點,把從源到u且中間只經過S中頂點的路稱為從源到u的特殊路徑,並用數組dist記錄當前每個頂點所對應的最短特殊路徑長度。Dijkstra算法每次從V-S中取出具有最短特殊路長度的頂點u,將u添加到S中,同時對數組dist作必要的修改。一旦S包含了所有V中頂點,dist就記錄了從源到所有其它頂點之間的最短路徑長度。
#include<iostream>
using namespace std;
const int maxn=205;
const int intmax=99999;
int weight[maxn][maxn]; //保存權值的鄰接矩陣
int dis[maxn];
int s,t;
void dijkstra()
{
bool Sset[maxn];
memset(Sset,0,sizeof(Sset));
Sset[s]=1;
for(int i=0;i<maxn;i++)
{
int u,v;
int tmp=intmax;
for(int i=0;i<maxn;i++)
{
if(!Sset[i]&&dis[i]<tmp)
{
u=i;
tmp=dis[i];
}
}
Sset[u]=1;
for(int i=0;i<maxn;i++)
{
if(!Sset[i]&&weight[u][i]<intmax)
{
int newdis=dis[u]+weight[u][i];
if(newdis<dis[i])dis[i]=newdis;
}
}
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
int a,b,x;
for(int i=0;i<maxn;i++)
for(int j=0;j<maxn;j++)
weight[i][j]=intmax;
for(int i=0;i<m;i++)
{
cin>>a>>b>>x;
if(x<weight[a][b]) //處理重邊
weight[a][b]=weight[b][a]=x;
}
cin>>s>>t;
for(int i=0;i<maxn;i++)dis[i]=weight[s][i];
dis[s]=0; //如果是起點到起點,則應該是0
dijkstra();
if(dis[t]<intmax)
cout<<dis[t]<<endl;
else cout<<-1<<endl; //不存的情況應該是:權值無窮大
}
return 0;
}
#include<iostream>
using namespace std;
const int maxn=205;
const int intmax=99999;
int weight[maxn][maxn]; //保存權值的鄰接矩陣
int dis[maxn];
int s,t;
void dijkstra()
{
bool Sset[maxn];
memset(Sset,0,sizeof(Sset));
Sset[s]=1;
for(int i=0;i<maxn;i++)
{
int u,v;
int tmp=intmax;
for(int i=0;i<maxn;i++)
{
if(!Sset[i]&&dis[i]<tmp)
{
u=i;
tmp=dis[i];
}
}
Sset[u]=1;
for(int i=0;i<maxn;i++)
{
if(!Sset[i]&&weight[u][i]<intmax)
{
int newdis=dis[u]+weight[u][i];
if(newdis<dis[i])dis[i]=newdis;
}
}
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
int a,b,x;
for(int i=0;i<maxn;i++)
for(int j=0;j<maxn;j++)
weight[i][j]=intmax;
for(int i=0;i<m;i++)
{
cin>>a>>b>>x;
if(x<weight[a][b]) //處理重邊
weight[a][b]=weight[b][a]=x;
}
cin>>s>>t;
for(int i=0;i<maxn;i++)dis[i]=weight[s][i];
dis[s]=0; //如果是起點到起點,則應該是0
dijkstra();
if(dis[t]<intmax)
cout<<dis[t]<<endl;
else cout<<-1<<endl; //不存的情況應該是:權值無窮大
}
return 0;
}