#include<bits/stdc++.h>
using namespace std;
int dp[1005],V[200];
int MAP[205][205];
const int inf=0x3f3f3f3f;
int minhh(int x,int y)
{
if(x<=y)return x;
else return y;
}
int main()
{
int i,N,M,S,T,min;
while(scanf("%d %d",&N,&M)!=EOF)
{
memset(V,0,sizeof(V));
memset(dp,inf,sizeof(dp));
memset(MAP,inf,sizeof(MAP));//初始化邻接矩阵为无穷大
for(i=0;i<N;i++)
{
V[i]=1;//能用的城市初始化
MAP[i][i]=0;//到自己距离为0
}
while(M--)
{
scanf("%d %d %d",&S,&T,&i);//征用S,T为临时变量
MAP[S][T]=minhh(MAP[S][T],i);//预防重复边
MAP[T][S]=MAP[S][T];//无向图,邻接矩阵对称
}
scanf("%d %d",&S,&T);
for(i=0;i<N;i++)dp[i]=MAP[S][i];//初始化最短距离数组
//录入题给信息
while(1)
{
dp[1000]=inf;min=1000;//初始化
for(i=0;i<N;i++)
{
if(V[i]==1&&dp[i]<dp[min])min=i;
}//找出最小边
if(min==T)break;//找到最短路径,结束循环
if(min==1000)break;//所有路径都考虑完了
V[min]=0;//表示这个城市考虑过了
for(i=0;i<N;i++)
{
if(V[i]==1&&dp[i]>dp[min]+MAP[min][i])
dp[i]=dp[min]+MAP[min][i];
}//松弛操作,更新到达每个城市的最短路径
}
if(dp[T]>=inf)printf("-1\n");
else printf("%d\n",dp[T]);
}
return 0;
}
总结:
1.程序卡住可以看看是不是循环结束条件有问题
2.DJ算法其实是依次找出从起点出发权值最小的路径(不一定是单纯的直达,可以是多条路径合成),并确认路径终点是否是目的地
错误案例(会超时,并没有体现动态规划简化计算的功能)
#include<bits/stdc++.h>
using namespace std;
//int dp[100005];
int MAP[205][205];
const int inf=0x3f3f3f3f;
int minhh(int x,int y)
{
if(x<=y)return x;
else return y;
}
int main()
{
int i,k,N,M,S,T;
while(scanf("%d %d",&N,&M)!=EOF)
{
memset(MAP,inf,sizeof(MAP));//初始化邻接矩阵为无穷大
while(M--)
{
scanf("%d %d %d",&S,&T,&i);//征用S,T为临时变量
MAP[S][T]=minhh(MAP[S][T],i);//预防重复边
MAP[T][S]=MAP[S][T];//无向图,邻接矩阵对称
}
scanf("%d %d",&S,&T);
//录入题给信息
M=0;//初始化M
if(S==T)printf("0\n");//如果是到原来城市
else while(M!=T)//直到最近点是目标点
{
for(i=0;i<N;i++)if(MAP[S][i]<MAP[S][M])M=i;//找出最近节点
if(M==T||MAP[S][M]>=inf)break;
else
{
for(i=0;i<N;i++)MAP[S][i]=minhh(MAP[S][M]+MAP[M][i],MAP[S][i]);//更新最短路径
MAP[S][M]=inf;//表示这个点已经走过了
}
}
if(MAP[S][T]>=inf)printf("-1\n");
else printf("%d\n",MAP[S][T]);
}
return 0;
}