一开始学的是dijk,然后还是挺好理解的(那是没接触过spfa...)
然后到了差分约束的时候接触了spfa...简直了!还好是学了BFS,这个spfa就是神好!
然后这题HDOJ1874又是很基础的那一种。贴两份代码(spfa还好看,dijk很难看》...《)
spfa代码(0MS)
spfa的算法思想
//建立表格记录起始点到所有点的最短路径(该表格的初始值要附作最大值,该点到它本身为0)
//然后进行松弛操作,用队列里的点作为起始点刷新到所有点的最短路,
//如果刷新成功且被刷新点不在队列里面,则把该点加到队列最后。
//重复执行直到队列为空。
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string.h>
#include <math.h>
#include<stdlib.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define N 250
int n,m;
int ma[N][N];
bool used[N];
int disj[N];
queue<int>q;
void init(int t)
{
int i,j;
for(i=0;i<n;i++)
{
disj[i]=INF;
for(j=0;j<n;j++)
{
ma[i][j]=INF;
}
}
memset(used,false,sizeof(used));
while(!q.empty())
q.pop();
}
void spfa(int s,int t)
{
int v;
disj[s]=0;
used[s]=true;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
used[u]=false;
for(v=0;v<n;v++)
{
if(ma[u][v]!=INF&&disj[u]+ma[u][v]<disj[v])
{
disj[v]=disj[u]+ma[u][v];
if(!used[v])
{
q.push(v);
used[v]=true;
}
}
}
}
if(disj[t]==INF)
printf("-1\n");
else
printf("%d\n",disj[t]);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int i;
init(n);
int a,b,c;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<ma[a][b])
ma[a][b]=ma[b][a]=c;
}
int s,t;
scanf("%d%d",&s,&t);
spfa(s,t);
}
return 0;
}
dijkstra
#include<stdio.h>
#include<string.h>
int tu[250][250];
#define N 99999999
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int n,m;
int j1,j2,j3,v,i,j;
int flag[250],d[250];
int begin,end,teen;
while(~scanf("%d%d",&n,&m))
{
memset(flag,0,sizeof(flag));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
tu[i][j]=N;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&j1,&j2,&j3);
if(tu[j1][j2]>j3)
tu[j1][j2]=tu[j2][j1]=j3;
}
scanf("%d%d",&begin,&end);
flag[begin]=1;
for(i=0;i<n;i++)
d[i]=tu[begin][i];
d[begin]=0;
for(i=0;i<n;i++)
{
teen=N;
for(j=0;j<n;j++)
{
if(flag[j]==0&&teen>d[j])
{
teen=d[j];
v=j;
}
}
if(teen==N)break;
flag[v]=1;
for(j=0;j<n;j++)
{
if(flag[j]==0)
{
d[j]=min(d[j],d[v]+tu[j][v]);
}
}
}
if(d[end]==N)
printf("-1\n");
else
printf("%d\n",d[end]);
}
return 0;
}