好多基础知识都没补完,只好看到、用到一个赶紧补全一个,并且保证下次需要的时候直接用,不用回来再补;

其实这个算法是在补同余最短路的时候用到的,当时突然发现理解算法导论上的原理甚至有效性证明,但是就是没办法写出来合适的代码。。于是到处寻找可以用来试验最短路径算法的试验场(当时学矩阵快速米的时候也是找了51nod上面的一到基础题作为测试的)来熟悉和不全最短路相关基础知识。

首先是DIJKSTRA

对于DIJKSTRA首先是个贪心算法,每次从集合中选择一条没有走过的最短路径来作为新的边,到达新的节点。在以当前找到的这条边更新所有可达的边——所谓的松弛操作。

可以证明,在n次这样的松弛操作之后,可以求得单元最短路(具体证明见算法导论)

这题的要求比单元最短路相对更高些,他要求找到最短路且权重最高的路径。因而应当在每次进行松弛操作时进行更新——当且仅当路径长度相同时选择更大的权重,其他时候选择更短的边的权重。

DIJKSTRA如下:

 #include<bits/stdc++.h>
using namespace std; const long long INF=1e12+;
const long long MAXN=1e3+;
long long dp[MAXN];
long long point[MAXN];
long long mon[MAXN];
long long path[MAXN][MAXN];
long long n,m,start,end; void init()
{
cin>>n>>m>>start>>end;
memset(mon,,sizeof(mon));
for(int i=;i<MAXN;++i)
for(int j=;j<MAXN;++j)path[i][j]=INF;
for(int i=;i<n;++i)
{
cin>>point[i];
dp[i]=INF;
}
for(int i=;i<m;++i)
{
int a,b,p;
cin>>a>>b>>p;
path[a][b]=p;
path[b][a]=p;
}
}
int v[MAXN];
void dijkstra()
{
memset(v,,sizeof(v));
int x=start;
mon[start]=point[start];
dp[start]=; //dijkstra初始化,应当以最起始点为0点
for(int i=;i<n;++i)
{
long long mini=INF;
for(int j=;j<n;++j)
{
if(!v[j]&&dp[j]<mini)
{
x=j;
mini=dp[j];
}
}v[x]=; //标记出现过的点
for(int j=;j<n;++j)
{
if(!v[j]&&dp[j]>dp[x]+path[x][j])
{ mon[j]=mon[x]+point[j];
}if(!v[j]&&dp[j]==dp[x]+path[x][j])//注意更新时确保该点没有被走到,否则可能出现重复更新
{
mon[j]=max(mon[j],mon[x]+point[j]);
} dp[j]=min(dp[x]+path[x][j],dp[j]);
}
}cout<<dp[end]<<" "<<mon[end]<<endl;
}
int main()
{
cin.sync_with_stdio(false);
init();
dijkstra();
return ;
}

堆优化的dijkstra,来自刘汝佳的蓝书,同样要注意简要修改下。

 #include<bits/stdc++.h>
using namespace std; const long long MAXN=+;
const long long INF=1e7+; class Edge
{
public:
long long from,to,dist;
}; class HeapNode
{
public:
long long d,u;
bool operator < (const HeapNode& h1)const
{
return this->d>h1.d;
}
}; long long mon[MAXN];
long long point[MAXN];
long long n1,m1,start,end; struct Dijkstra
{
long long n,m;
vector<Edge> edges;
vector<long long> G[MAXN];
bool done[MAXN];
long long d[MAXN];
long long p[MAXN]; void init(long long n)
{
this->n=n;
for(long long i=;i<n;++i)
{
G[i].clear();
}edges.clear();
} void AddEdge(long long from,long long to,long long dist)
{
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-);
} void dijkstra(long long s)
{
priority_queue<HeapNode> Q;
for(long long i=;i<n;++i)d[i]=INF;
d[s]=;
memset(done,,sizeof(done));
Q.push((HeapNode){,s});
mon[s]=point[s];
while(!Q.empty())
{
HeapNode x=Q.top();Q.pop();
long long u=x.u;
if(done[u])continue;
done[u]=true;
for(long long i=;i<G[u].size();++i)
{
Edge &e=edges[G[u][i]];
if(d[e.to]>d[u]+e.dist)
{
d[e.to]=d[u]+e.dist;
p[e.to]=G[u][i];
Q.push((HeapNode){d[e.to],e.to});
mon[e.to]=mon[u]+point[e.to];
}else if(d[e.to]==d[u]+e.dist)
mon[e.to]=max(mon[u]+point[e.to],mon[e.to]);
}
}
}
}; int main()
{
cin.sync_with_stdio(false);
Dijkstra d1;
cin>>n1>>m1>>start>>end;
for(long long i=;i<n1;++i)cin>>point[i];
d1.init(n1);
for(long long i=;i<m1;++i)
{
long long a,b,p;cin>>a>>b>>p;
d1.AddEdge(a,b,p);
d1.AddEdge(b,a,p);
}
d1.dijkstra(start); cout<<d1.d[end]<<" "<<mon[end]<<endl; return ;
}

Bellman_Ford算法:
首先,算法思路:设定某有向图中,不存在负环,则对于每条最短路,都会在每一轮松弛中,得到至少一条最短路。

若有向图G中,有一条最短路:A->B->C->D->E,那么因为起始节点为A,则A->B的最短路径会在第一轮松弛操作时被找到。而后操作也是同理。接下来的每个最短路元素都会在未来的某一次松弛操作中被找到。因为每轮松弛操作都至少找到一个元素,所以我们应当认为

51nod_1459 最短路 dijkstra 特调参数的更多相关文章

  1. 华夏60 战斗机(最短路dijkstra)

    华夏60 战斗机(最短路dijkstra) 华夏60 超音速战斗机是当今世界上机动性能最先进的战斗机.战斗过程中的一个关键问题是如何在最短的时间内使飞机从当前的飞行高度和速度爬升/俯冲到指定的高度并达 ...

  2. hdu 2544 最短路 Dijkstra

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 题目分析:比较简单的最短路算法应用.题目告知起点与终点的位置,以及各路口之间路径到达所需的时间, ...

  3. 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法

    图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...

  4. GBDT、XGBOOST、LightGBM调参数

    总的认识: LightGBM  > XGBOOST  > GBDT 都是调参数比较麻烦. GBDT分类的最佳调参数的讲解: Gradient Boosting Machine(GBM)调参 ...

  5. 单源最短路dijkstra算法&&优化史

    一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...

  6. HUD.2544 最短路 (Dijkstra)

    HUD.2544 最短路 (Dijkstra) 题意分析 1表示起点,n表示起点(或者颠倒过来也可以) 建立无向图 从n或者1跑dij即可. 代码总览 #include <bits/stdc++ ...

  7. 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

    layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...

  8. 训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

    layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...

  9. 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)

    layout: post title: 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板) author: "luowentaoaa" catalo ...

随机推荐

  1. 基于FCM的消息推送功能

    需求背景 我方项目需要支持客户端消息推送,iOS终端可以借由苹果本身的apns很方便的实现,但是对于Android来说,必须集成第三方的SDK来处理.考虑到项目需要以及成本,我们选择使用谷歌的FCM框 ...

  2. 安卓adb调试命令常见的问题

    首先本人使用的是ubuntu系统,在Eclipse下开发的时候使用无线调试,在终端直接输入adb connect 114.114.114.114没有问题,给手机安装软件用adb install  ** ...

  3. Catch the moments of your life. Catch them while you're young and quick.

    Catch the moments of your life. Catch them while you're young and quick.趁你还年轻利落,把握住生活中的美好瞬间吧!

  4. 碎碎念css

    块状元素单独占一行,但加上float变成跟着别人,有空就插!float让块级元素变行内元素

  5. C++ 宏定义的简单使用

    1.定义常量 #define ARRMAX 50 int arr[ARRMAX]; (这种做法不如直接用const来直接定义常量.) 2.代替模板函数或者内联函数,将函数定义成宏.执行效率很快 #de ...

  6. git简易使用指南

    git简易使用指南 Git是一个分布式版本控制/软件配置管理软件,原是Linux内核开发者林纳斯·托瓦兹(Linus Torvalds)为更好地管理Linux内核开发而设计.应注意的是,这与GNU I ...

  7. 弹出页面第一次加载可以生成table和方法的绑定,第二次点击进来不能生成table和方法的帮定

    问题原因: 弹出页面的写法是每次点击都会在原有页面基础之上新添加一个将其覆盖,原有页面不关闭.我用的生成table和点击事件的绑定是id选择器.页面中只绑定第一次的页面,第二次的页面作用不上. 解决: ...

  8. cloudera manager的卸载以及重新安装

    1 卸载cloudera 参照 http://www.cnblogs.com/chenfool/p/3738540.html Cloudera 的官方介绍: http://www.cloudera.c ...

  9. 漫谈 Clustering (番外篇): Expectation Maximization

    Expectation Maximization (EM) 是一种以迭代的方式来解决一类特殊最大似然 (Maximum Likelihood) 问题的方法,这类问题通常是无法直接求得最优解,但是如果引 ...

  10. python linecache模块读取文件用法详解

    linecache模块允许从任何文件里得到任何的行,并且使用缓存进行优化,常见的情况是从单个文件读取多行. linecache.getlines(filename) 从名为filename的文件中得到 ...