Dijkstra:
//不能解决有负边权的图
//从起点一层层向下更新
//与spfa(靠队列实现)相似,源点是一定的,but 实现方式不同
#include<cstdio>
#define Max 0x3fffffff
int map[1005][1005];
int dis[1005];
void dijkstra(int n)
{
int visit[1001]={0};
int min,i,j,k;
visit[1]=1;
for(i=1;i<n;++i)
{
min=Max;
k=1;
for(j=1;j<=n;++j)
{
if(!visit[j]&&min>dis[j])
{
min=dis[j];
k=j;
}
}
visit[k]=1;
for(j=1;j<=n;++j)
{
if(!visit[j]&&dis[j]>dis[k]+map[k][j])
dis[j]=dis[k]+map[k][j];
}
}
printf("%d\n",dis[n]);
}
int main()
{
int t,n,i,j,from,to,cost;
while(scanf("%d%d",&t,&n)!=EOF)
{
for(i=1;i<=n;++i)
{
map[i][i]=0;
for(j=1;j<i;++j)
map[i][j]=map[j][i]=Max;
}
for(i=1;i<=t;++i)
{
scanf("%d%d%d",&from,&to,&cost);
if(cost<map[from][to])
map[from][to]=map[to][from]=cost;
}
for(i=1;i<=n;++i)
dis[i]=map[1][i];
dijkstra(n);
}
return 0;
}
SPFA:
//期望的时间复杂度为o(ke),k为所有顶点的进队次数,k一般<=2
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 1000001
#define inf 0x7ffffff
using namespace std;
int n,m,tot;
int head[maxn],next[maxn],dist[maxn];
bool vis[maxn];
struct node
{
int from,to,w;
}e[maxn];
void add(int from,int to,int w)
{
e[++tot] = (node){from,to,w};
next[tot] = head[from];
head[from] = tot;
/* e[t].from=i;
e[t].to=j;
e[t].w=w;
e[t].next=head[i];
head[i]=++t;
*/
}
//先将源点入队,再依次取与当前点(已经处理完最短路的点)相邻的点
void spfa(int s)
{
queue<int> q;
for(int i=1;i<=n;i++) dist[i]=inf;
q.push(s);
vis[s]=true;
dist[s]=0;
while(!q.empty())
{//通过for循环解决的是与u相邻的所有点与边,即:处理(取出)一个点,就用for循环更新完与他相邻的点的zdl
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=next[i])
{//从以源点为起点的边开始循环,e[i].next:当前边的下一条边(同一个起点)
int v=e[i].to;
if(dist[v]>dist[u]+e[i].w)
{
dist[v]=dist[u]+e[i].w;
if(!vis[v])//没有在队列中(是否之前入队过,又出队,vis才==0??????)
{
q.push(v);
vis[v]=true;
}
}
}
}
}
int main()
{
freopen("spfa.in","r",stdin);
freopen("spfa.out","w",stdout);
int a,b,c,s,e;
//t=0;
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
//如果双向边边权不一样 也不影响,因为是一直朝着终点走,一条边不会走两遍
// !!!
}
//求s->e的最短路(zdl)
scanf("%d%d",&s,&e);
spfa(s);
if(dist[e]==inf) printf("-1\n");
else printf("%d",dist[e]);
return 0;
}
..........有bug...............
#include<iostream>
#include<cstdio>
#include<queue>
#define maxx 1000007
using namespace std;
int n,m,tot=0;
int first[maxx],next[maxx],dis[maxx];
struct bian
{
int f,t,d;
}b[10005];
void build(int f,int t,int d)
{
b[++tot]=(bian){f,t,d};
next[tot]=first[f];
first[f]=tot;
}
queue<int>q;
bool used[10005];
//每次将与当前点相邻的点入队
void spfa(int x)
{
for(int i=1;i<=n;i++)
dis[i]=1e9;
dis[x]=0;
q.push(x);
used[x]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
used[u]=0;
for(int i=first[u];i!=0;i=next[i])
{
int v=b[i].t;
if(dis[v]>dis[u]+b[i].d)
{
dis[v]=dis[u]+b[i].d;
if(used[v]==0)
{
q.push(v);
used[v]=1;
}
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,z;
build(x,y,z);
build(y,x,z);
}
spfa(1);
cout<<dis[n]<<endl;
return 0;
}
/*..........邻接表存图有bug,待改正
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 1000001
#define inf 0x7ffffff
using namespace std;
int n,m,t;
int head[maxn],dist[maxn];
bool vis[maxn];
struct node
{
int from,to,w,next;
}e[maxn];
void add(int i,int j,int w)
{
e[t].from=i;
e[t].to=j;
e[t].w=w;
e[t].next=head[i];
head[i]=++t;
}
int spfa(int s)
{
queue<int> q;
for(int i=1;i<=n;i++) dist[i]=inf;
q.push(s);
vis[s]=true;
dist[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
if(dist[v]>dist[u]+e[i].w)
{
dist[v]=dist[u]+e[i].w;
if(!vis[v])
{
q.push(v);
vis[v]=true;
}
}
}
}
}
int main()
{
int a,b,c,s,e;
t=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
scanf("%d%d",&s,&e);
spfa(s);
if(dist[e]==inf) printf("-1\n");
else printf("%d",dist[e]);
return 0;
}
*/
Floyd:
// for * 3
//n:节点个数
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if(dis[i][k] + dis[k][j] < dis[i][j] )
{
//更新最短路径
dis[i][j] = dis[i][k] + dis[k][j];
}
}
}
}