!!!
prim算法和dijkstra算法虽然求解的最终目的不同,但结构是非常相似的,都是从已知的点的集合U向未知的点的集合V扩展,不同在于prim算法是将U看做一个集合,这样在选出一个新的点pos后,需要比较的是pos到map上所有点的距离,如果有更小的,更新dist[]。
而dijkstra是将原始的点作为参考基准,每次得到一个新的点后,比较原来的map[s][j]和dist[pos]+map[pos][j]的大小,如果点s经过pos之后到到另一个点的距离更小,更新dist[i]。
先附上一开始写的代码,测试用例没有问题,但你发现为什么它一直通不过了吗?
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000;
const int INF=999999;
int n,m;
int map[maxn][maxn];
int dist[maxn];
void dijkstra(int s,int e)
{
int i,j,k;
int visit[maxn];int pos;
memset(visit,0,sizeof(visit));
visit[s]=1;
for(i=0;i<n;i++)
{
int minu=INF;
for(j=0;j<n;j++)
{
if(!visit[j]&&dist[j]!=-1&&dist[j]<minu) //这里如果用map[s][j]的话就不能起到复用的效果
{
pos=j;
minu=dist[j];
}
}
visit[pos]=1;
for(j=0;j<n;j++)
{
if(!visit[j] && map[pos][j]!=-1)
{
int newdist=dist[pos]+map[pos][j];
if(dist[j]>newdist) dist[j]=newdist;
}
}
}
}
int main(void)
{
int i,j,k;
int a,b,c;
int s,e;
while(cin>>n>>m)
{
memset(map,-1,sizeof(map));
//cin>>m;
for(i=0;i<m;i++)
{
cin>>a>>b>>c;
if(map[a][b]!=-1&&c>map[a][b]) continue;
else map[a][b]=map[b][a]=c;
}
cin>>s>>e;
for(i=0;i<n;i++)
dist[i]=map[s][i];
dist[s]=0; //??
dijkstra(s,e);
if(dist[e]!=-1) cout<<dist[e]<<endl;
else cout<<-1<<endl;
}
}
这是自己仔细想清楚后再写的,AC。对于两个不能达到的点,它们的距离不是-1,而是INF。如果初始化为-1的话,在进行比较时,新计算的点的距离无论如何也会比-1(原始的距离)大,根本达不到比较的效果。算法书在实现时假设的就是INF,恩,怎么说呢,自己在实现时还是出了一些小问题~
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000;
const int INF=999999;
int n,m;
int map[maxn][maxn];
int dist[maxn];
void dijkstra(int s,int e)
{
int i,j,k;
int visit[maxn];int pos;
memset(visit,0,sizeof(visit));
visit[s]=1;
for(i=0;i<n;i++)
{
int minu=INF;
for(j=0;j<n;j++)
{
if(!visit[j]&&dist[j]<minu) //这里如果用map[s][j]的话就不能起到复用的效果
{
pos=j;
minu=dist[j];
}
}
visit[pos]=1;
for(j=0;j<n;j++) //怎么能是-1......
{
if(!visit[j] && map[pos][j]!=INF)
{
int newdist=dist[pos]+map[pos][j];
if(dist[j]>newdist) dist[j]=newdist;
}
}
}
}
int main(void)
{
int i,j,k;
int a,b,c;
int s,e;
while(cin>>n>>m)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
map[i][j]=INF;
//cin>>m;
for(i=0;i<m;i++)
{
cin>>a>>b>>c;
if(c<map[a][b])
map[a][b]=map[b][a]=c;
}
cin>>s>>e;
for(i=0;i<n;i++)
{
dist[i]=map[s][i];
//map[i][i]=0; //??
}
dijkstra(s,e);
dist[s]=0;
if(dist[e]!=INF) cout<<dist[e]<<endl;
else cout<<-1<<endl;
}
}