此处不解释算法,只写代码模板。
Dijkstra
邻接矩阵实现
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
int map[110][110];
int dis[110];
int visit[110];
/*
关于三个数组:map数组存的为点边的信息,比如map[1][2]=3,表示1号点和2号点的距离为3
dis数组存的为起始点与每个点的最短距离,比如dis[3]=5,表示起始点与3号点最短距离为5
visit数组存的为0或者1,1表示已经走过这个点。
*/
int n,m;
int dijkstra()
{
int i,j,pos=1,min,sum=0;
memset(visit,0,sizeof(visit));//初始化为0,表示开始都没走过
for(i=1; i<=n; i++)
{
dis[i]=map[1][i];
}
visit[1]=1;
dis[1]=0;
int T=n-1;
while(T--)
{
min=MAX;
for(j=1; j<=n; j++)
{
if(visit[j]==0&&min>dis[j])
{
min=dis[j];
pos=j;
}
}
visit[pos]=1;//表示这个点已经走过
for(j=1; j<=n; j++)
{
if(visit[j]==0&&dis[j]>min+map[pos][j])//更新dis的值
dis[j]=map[pos][j]+min;
}
}
return dis[n];
}
int main()
{
int i,j;
while(cin>>n>>m)//n表示n个点,m表示m条边
{
memset(map,MAX,sizeof(map));
int a,b,c;
for(i=1; i<=m; i++)
{
cin>>a>>b>>c;
if(c<map[a][b])//防止有重边
map[a][b]=map[b][a]=c;
}
int sum=dijkstra();
cout<<sum<<endl;
}
return 0;
}
vector邻接表实现
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int end;//终点
int power;//权值
} t;
int n;//n为边数
vector<node>q[500001];//邻接表存储图的信息
int dis[500001];//距离数组
bool vis[500001];//标记数组
void Dijkstra(int start, int end)
{
memset(vis, false, sizeof(vis));
for(int i=0; i<=n; i++)
{
dis[i] = INF;
}
int len=q[start].size();
for(int i=0; i<len; i++)
{
if(q[start][i].power < dis[q[start][i].end] )
dis[q[start][i].end]=q[start][i].power; //从起点开始的dis数组更新
}
vis[start]=true;//起点标记为1
for(int k=0; k<n-1; k++)
{
int pos, min=INF;
for(int i=1; i<=n; i++)
{
if( !vis[i] && dis[i]<min )
{
//当前节点未被访问过且权值较小
min=dis[i];
pos=i;
}
}
vis[pos]=true;
//再次更新dis数组
len=q[pos].size();
for(int j=0; j<len; j++)
{
if( !vis[q[pos][j].end] && dis[ q[pos][j].end ]>q[pos][j].power+dis[pos] )
dis[q[pos][j].end ] = q[pos][j].power + dis[pos];
}
}
printf("%d\n", dis[end] );
}
int main()
{
int m;
while(scanf("%d %d", &n, &m)&&n&&m)//输入点和边
{
for(int i=0; i<=n; i++)
q[i].clear();//将vector数组清空
for(int i=0; i<m; i++)
{
int begin,end, power;
scanf("%d %d %d", &begin, &end, &power);//输入
/*t作为node型临时变量,为了方便压入,以下代码为无向图的输入边*/
t.end=end;
t.power=power;
q[begin].push_back(t);
t.end=begin;
t.power=power;
q[end].push_back(t);
}
//Dijkstra(1, n);
int start, end;//自己确定起始点和终止点
scanf("%d %d", &start, &end);//输入起始点和终止点
Dijkstra(start, end);
}
return 0;
}
Floyd
#include<iostream>
#include <cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
int map[1100][1100];
void floyd(int n)
{
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]); //这里用了min函数,可能会多一点耗时。
}
int main()
{
int i,j,n,m; //读入n和m,n表示顶点个数,m表示边的条数
cin>>n>>m;
memset(map,MAX,sizeof(map)); //初始化
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
if(i==j)
map[i][j]=0;
int a,b,c;
for(i=1; i<=m; i++)
{
cin>>a>>b>>c;
map[a][b]=c;//这是一个有向图
}
floyd(n);
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
cout<<map[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
Bellman-Ford
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
const int N=1010;
int nodenum, edgenum, source; //点,边,起点
typedef struct Edge
{
int st;
int ed;
int power;
} Edge;
Edge edge[N];
int dis[N];
void inite() //初始化图
{
cin>>nodenum>>edgenum>>source;
memset(dis,MAX,sizeof(dis));
dis[source]=0;
for(int i=1; i<=edgenum; i++)
{
cin>>edge[i].st>>edge[i].ed>>edge[i].power;
if(edge[i].st == source) //注意这里设置初始情况
dis[edge[i].ed] = edge[i].power;
}
}
void relax(int st,int ed,int power) //松弛计算
{
if(dis[ed]>dis[st]+power)
dis[ed]=dis[st]+power;
}
bool Bellman_Ford()
{
for(int i = 1; i <= nodenum - 1; i++)
for(int j = 1; j <= edgenum; j++)
relax(edge[j].st,edge[j].ed,edge[j].power);
for(int i = 1; i <= edgenum; ++i)
{
if(dis[edge[i].ed] > dis[edge[i].st] + edge[i].power)
{
return 0;
}
}
return 1;
}
int main()
{
inite();
if(Bellman_Ford())//如果没有负权
{
for(int i = 1; i <= nodenum; ++i) //每个点最短路
{
cout<<dis[i]<<" ";
}
cout<<endl;
}
return 0;
}
SPFA
poj 2387
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<utility>
#include<algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define swap(a,b) (a=a+b,b=a-b,a=a-b)
//#define memset(a) memset(a,0,sizeof(a))
#define X (sqrt(5)+1)/2.0 //Wythoff
#define Pi acos(-1)
#define e 2.718281828459045
using namespace std;
typedef long long int LL;
typedef pair<int,int>pa;
const int MAXL(1e3);
const int INF(0x3f3f3f3f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
vector<pa>v[MAXL+50];
int vis[MAXL+50];
int dis[MAXL+50];
int SPFA(int s,int n)
{
queue<int>q;
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i].first,y=v[u][i].second;
if(dis[u]+y<dis[x])
{
dis[x]=dis[u]+y;
if(!vis[x])
{
q.push(x);
vis[x]=1;
}
}
}
}
return dis[n];
}
int main()
{
int T,n;
cin>>T>>n;
for(int i=1;i<=T;i++)
{
int x,y,z;
cin>>x>>y>>z;
pa p;
p=make_pair(y,z);
v[x].push_back(p);
p=make_pair(x,z);
v[y].push_back(p);
}
int ans=SPFA(1,n);
cout<<ans<<endl;
}