鄙人才大二,刚刚接触图论,刚开始的时候也是各种看不懂,慢慢的老看动图老做题慢慢也开始理解了。。
dijkstra算法的核心个人理解就是:最终目的是形成一条标记好的路线,先确定一个点开始,然后找所有的点中dis(也就是到起点的距离最短的那个点)中最小的,标记他作为我们这条路线上的点,然后从这点出发更新与这一点直连的所有点的dis,算是一次“松弛操作”,最后每个点距离起点的最短路都变成了dis数组中的数
dijkstra禁用在有负数边的情况里,这种情况一般用更简单但复杂度高的 Bellon-Ford算法。
个人感觉图论这种东西不要被模板,深刻理解模板的意思,然后拿来会改动以应付各种题才是出路,做题不是教主的话别老自己造轮子,借力哈哈
AC:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXINT = 1000000;
const int MAXNUM = 500;
int dist[MAXNUM];
int A[MAXNUM][MAXNUM];
bool S[MAXNUM];
void dijkstra(int v0,int n0)
{
int i, j, u , min;
for(i=0;i<n0;i++)
{
dist[i]=A[v0][i];
S[i]=false;
//if(i!=v&&adj[v][i]!=INF)pre[i] = v;
// else pre[i] = -1;
}
S[v0]=1;dist[v0]=0;
for(i=0;i<n0;i++)
{
min = MAXINT;
for(j=0;j<n0;j++)
{
if(!S[j]&&min > dist[j])
{
min = dist[j];
u = j;
}
}
if(min == MAXINT)break;
S[u]=true;
for(j=0;j<n0;j++)
{
if(!S[j]&&A[u][j]!=MAXINT&&dist[u]+A[u][j]<dist[j])
{
dist[j] = A[u][j] + dist[u];
// pre[j] = u;
}
}
}
}
int main()
{
int nn,m;
int a,b,x;
int bgin,end;
while(scanf("%d %d",&nn,&m)!=EOF)
{
for(int i=0;i<300;i++)
{
for(int j=0;j<300;j++)
A[i][j]=MAXINT;
}
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&a,&b,&x);
if(A[a][b]>x)
A[a][b]=A[b][a]=x;
}
scanf("%d %d",&bgin,&end);
dijkstra(bgin,nn);
if(dist[end]==MAXINT)
printf("-1\n");
else
cout<<dist[end]<<endl;
}
return 0;
}
ps:哦对了,补充一句,这题有个烦人的地方就是某两城市之间的路线X值可能有多个,要选一个最小的(就这里wa了两次。。。)