最短路专题(最全面详细解决最短路问题的一篇博文)
题意:就是让我们求从商场到赛场的最短距离
我们先来看下暴力解法~
1.我们首先建立一个邻接矩阵mapt来表示从 i 到 j 存在一条路;
2.首先我们知道在给这个mapt初始化时在主对角线上的元素,及 i == j ,表示的是从自身到自身,那么我们自然要给其初始化为0, 其余的我们统统看成没有路,即为INF。
3.然后我们要输入题目中所给的路径,因为由题意我们要构造的图应该是无向的,所以从i 到 j和从 j 到 i 应该路径都是相同的。
4.在这之后,自然是将所有可能的结果都计算然后从中取最小值即可。(最外面的一层应该是中间端点,随后两个for是两端点) 如果多走一个节点能使距离减少,那么我们自然要将此时从i到j的最短距离更新了。
5.然后我们就能得到从任意端点到任意端点的最短距离了,存在mapt中,我们按照题意输出即可~~
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 105
int mapt[maxn][maxn];
int main(){
int n,m;
while(cin>>n>>m && n+m){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j){
mapt[i][j] = 0;
}
else
mapt[i][j] = inf;
}
int x,y,z;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
if(mapt[x][y]>z)
mapt[x][y]= mapt[y][x] = z;
}
for(int k =1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(mapt[i][j]>mapt[i][k]+mapt[k][j])
mapt[i][j]=mapt[i][k]+mapt[k][j];
}
cout<<mapt[1][n]<<endl;
}
return 0;
}
然后欣赏完暴力学的美感后,我们来看一下如何优化。 dijsktra算法~~(单源最短路径,只能处理正权的边) 运行时间整整少了一半呢!!是不是很感人~(⊙o⊙)…
#include <iostream>
using namespace std;
#define inf 0x3f3f3f3f//无限大
int map[105][105],dis[105],vis[105];//mapt作用同上用来存图,dis表示最短距离,vis表示是否访问过~
int n,m;
void dijkstra(int start) //重点还是dijsktra这个函数,处理的是将dis更新为能存在的最短路径~
{
int i,j,k;
for(i=1; i<=n; i++)//这里相当于对这个dis进行初始化
{
dis[i]=map[start][i];
}
for(i=1;i<=n;i++)
vis[i]=0;//访问过得话为1,没有访问过得话为0; vis的初始化 ;
vis[start]=1;//因为我们是从这里开始的,所以可以直接记为1.表示访问过了。
for(i=1;i<=n-1;i++) //这个位置呢,是我们遍历端点(建议看下理论推导过程后再看,本博客只详细讲解代码)
{
int mix=inf;
int u;
for(j=1;j<=n;j++)
{
if(vis[j]==0 && mix>dis[j])//我们将所有的边遍历,然后从中找到与start相通的最短的那一个
{
mix=dis[j];//我们将其更新为最短路径
u=j;//标记
}
}
vis[u]=1;//更新为访问过了
for(k=1;k<=n;k++)//可能有些端点经过更多点后距离变得更短了
{
if(vis[k]==0 && dis[k]>dis[u]+map[u][k])
dis[k]=dis[u]+map[u][k];
}
}//注意第一个for循环得结尾在这里!
}
int main()
{
int i,j,k;
while(cin>>n>>m && n || m)
{
for(i=1;i<=n;i++)//这一部分依然是存图~
for(j=1;j<=n;j++)
{
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
}
while(m--)//这里是路径的输入
{
int x,y,z;
cin>>x>>y>>z;
if(map[x][y]>z)
{
map[x][y]=map[y][x]=z; //无向图
}
}
dijkstra(1);//这里表示从1开始求到各顶点的最短距离~
cout<<dis[n]<<endl;//想求哪个直接输出就行了~
}
return 0;
}
A - Til the Cows Come Home
题意:意思大概就是他想睡懒觉,然后要早点回去,你要找到一个最短的路让他回去,是不是很有用的算法啊~ 你看完后肯定说!哇,几乎一模一样哎!对哦,这是最简单的模范题哦,把这些深刻领会了,再加上你自己的聪明才智,ACM金牌爷就是您啊!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 0x3f3f3f3f
using namespace std ;
int u , v ,n, dis[1111],vis[1111],ma[1111][1111];
void dijk()
{
int k , mini;
for(int i = 1 ; i <=v;i++)
{
dis[i]=ma[1][i];
}
for(int i = 1 ;i<=v;i++)
{
mini=MAX;
for(int j = 1 ; j<=v;j++)
{
if(!vis[j]&&dis[j]<mini)
{
mini=dis[j];
k=j;
}
}
vis[k]=1;
for(int j=1 ;j<=v;j++)
{
if(dis[j]>dis[k]+ma[k][j])
{
dis[j]=dis[k]+ma[k][j];
}
}
}
}
int main()
{
while(cin>>u>>v)
{
n=0;
for(int i = 0 ; i <=v;i++)
{
for(int j = 0 ; j <=v;j++)
{
ma[i][j] = MAX;
}
ma[i][i]=0;
vis[i]=0;
dis[i]=MAX;
}//这里是所有的初始化,我感觉这样写很吊的感觉~嘿嘿嘿
for(int i = 1;i<=u;i++)
{
int a , b , len;
cin>>a>>b>>len;
n=max(max(n,a),b);
if(ma[a][b]>len)
{
ma[a][b]=ma[b][a]=len;
}
}
dijk();
printf("%dn",dis[v]);
}
return 0 ;
}
B - 畅通工程续 题意:这不就是找路最短嘛!!!
这该死的模板,这样在练不会就没脸泡妞了!!!(你说似吧)
#include<bits/stdc++.h>
using namespace std;
#define N 205
#define inf 0x3f3f3f3f
int dis[N],w[N][N],n,m,x,y;
bool vis[N];
void dijstra()
{
int i,j;
for(i=0;i<n;i++)
{
dis[i]=w[x][i];
vis[i]=0;
}
dis[x]=0;
vis[x]=1;
for(i=0;i<n;i++)
{
int mark,mindis=inf;
for(j=0;j<n;j++)
{
if(!vis[j]&&dis[j]<mindis)
{
mindis=dis[j];
mark=j;
}
}
//if(mindis==inf) break;
vis[mark]=1;
for(j=0;j<n;j++)
{
if(!vis[j])
{
dis[j]=min(dis[j],dis[mark]+w[mark][j]);
}
}
}
if(dis[y]==inf)
printf("-1n");
else printf("%dn",dis[y]);
}
void init()
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
w[i][j]=inf;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,a,b,c;
init();
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<w[a][b]) w[a][b]=w[b][a]=c;
}
scanf("%d%d",&x,&y);
dijstra();
}
return 0;
}
Currency Exchange 那你肯定说:遇到负权问题怎么办啊!? 你怎么就这么好学呢!!! 程序学好就能有女朋友! 什么?!!! 那让我们来一起为将来的那个可爱的女孩努力钻研这深奥的代码吧!毕竟我们的头发能给她换来mo+++.
#include<iostream>
using namespace std;
double dis[109];
int tol;
int R[209][2];
double C[209][2];
bool Bellman( int s ,int n ,double v ){
for( int i=1;i<=n;i++)
dis[i] = 0;
dis[s] = v;
for( int i=1;i<n;i++){
bool flag = false;
for( int j=0;j<tol;j++){
int u = R[j][0];
int v = R[j][1];
if( dis[v] < ( dis[u] - C[j][1]) * C[j][0 ] ){
flag = true;
dis[v] = ( dis[u] - C[j][1]) * C[j][0];
}
}
if( !flag )
return false;
}
for( int j=0;j<tol;j++){
if( dis[ R[j][1] ] < ( dis[ R[j][0] ] - C[j][1] ) * C[j][0] )
return true;
}
return false;
}
int main(){
int n,m , s;
double v;
while( scanf(" %d %d %d %lf",&n,&m,&s,&v) !=EOF){
tol = 0;
int a,b;
double c,d,e,f;
while( m-- ){
scanf("%d%d%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
R[tol][0] = a;
R[tol][1] = b;
C[tol][0] = c;
C[tol][1] = d;
tol++;
R[tol][0] = b;
R[tol][1] = a;
C[tol][0] = e;
C[tol][1] = f;
tol++;
}
if( Bellman(s ,n,v) )
printf("YESn");
else printf("NOn");
}
return 0;
}
Travel Company
题意:让你来判断有无负环~是不是太典型了
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 205
int dis[maxn],cnt,n;
struct node{
int u,v,w;
}edge[1000000];
void add(int u,int v,int w){
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt++].w = w;
}
void Berman(){
memset(dis,inf,sizeof(dis));
int i,j;
for(int i=0;i<n-1;i++){
for(int j=0;j<cnt;j++){
if(dis[edge[j].v]>dis[edge[j].u]+edge[j].w)
{
dis[edge[j].v]=dis[edge[j].u]+edge[j].w;
}
}
}
for(int i=0;i<cnt;i++){
if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
{
printf("YESn");
return ;
}
}
cout<<"NO"<<endl;
}
int main(){
int t,u,v,w,cost,m,num=0,p;
cin>>t;
while(t--){
num++;
cin>>n>>m>>p;
cnt= 0;
while(m--){
cin>>u>>v>>w>>cost;
add(u,v,cost*p-w);
}
printf("Case %d: ",num);
Berman();
}
return 0;
}
- 【腾讯云的1001种玩法】试用腾讯云 Windows Server 2012 R2 镜像的几点经验分享
- 一个只有99行代码的JS流程框架(二)
- 看书的时候如何调试书中简单的C+代码?
- gcForest 集成学习方法的 Python 实现
- 云端架构师养成系列之一:高性能云硬盘入门与实战(视频)
- 云端架构师养成系列之二:云端负载均衡上手与实践
- 微信 PaxosStore:海量数据冷热分级架构
- 使用腾讯云容器服务来构建简单web service
- 使用 plotly 绘制数据图表
- 基于云计算的 CV 移动交互应用研究:头部姿态估计综述(2)
- 使用 trie 树实现简单的中文分词
- 重磅发布!2017年度 DevOps 现状调查报告中文完整版!
- AI 泡沫前,我们怎么办?中美两国人工智能产业发展全面解读
- 养车记账本小程序开发实例
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- cURL-7.72.0初体验(参数写法)
- 21道前端面试题,值得收藏~
- OpenCV4.4 CUDA编译与加速全解析
- JavaScript中的Event Loop机制详解(前端必看)
- HDFS集群缩容案例: Decommission DataNode
- 应用深度学习进行乳腺癌检测
- 为什么你的数据仓库项目推进不下去?
- 19个有趣的Linux 命令,最后一个?... 打死我都不敢尝试!
- SpringBoot 整合 Quartz 实现 JAVA 定时任务的动态配置
- 使用 IntelliJ IDEA 查看类图,内容极度舒适
- 精选10款谷歌浏览器插件武装你的浏览器
- 王者荣耀为什么不使用微服务架构?
- Dubbo 时间轮
- Spring Boot 无侵入式 实现API接口统一JSON格式返回
- 监控、链路追踪、日志这三者有何区别?