1
//最少转机:广度优先
//两个点之间最短路径:深度搜索
//任意两点的最短路径:只有五行的算法-Floyd Warshall
void floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(e[i][j] > e[i][k] + e[k][j])
e[i][j] = e[i][k] + e[k][j];
}
}
}
}
//单源最短路径:dijkstra
void dijsktra(){
for(i=1;i<=n-1;i++){ //进行n-1轮松弛
min=inf;
for(j=1;j<=n;j++){ //找出距离最近的点
if(book[j]==0 && dis[j]<min){
min=dis[j];
u=j;
}
}
book[u]=1;
for(v=1;v<=n;v++){ //更新到所有点的最短距离
if(e[u][v]<inf){
if(dis[v]>dis[u]=e[u][v])
dis[v]=dis[u]=e[u][v]
}
}
}
}
//单源最短路径:bellman,解决负权边
void bellman(){
for(k=1;k<=n-1;k++){ //最多进行n-1轮松弛
check=0;
for(i=1;i<=m;i++){ //对每一条边进行松弛
if(dis[v[i]] > dis[u[i]] + w[i]){
dis[v[i]] = dis[u[i]] + w[i];
check=1;
}
}
if(check==0) break;
}
//n-1轮松弛后,仍然可以松弛,说明有回路
}
//单源最短路径:bellman的队列优化
//图的最小生成树:用最少的边长让图连通(任意两点互相到达)kruskal
void kruskal(){
for(i=1;i<=m;i++){ //开始从小到大枚举每一条边
if(merge(e[i].u, e[i].v)){ //如果两个顶点还未连通的话,连通它
count++;
sum+=e[i].w;
}
if(count==n-1) //选用了n-1条边后退出
break;
}
}
2