最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html
d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到这个城市的距离设为0),草儿想去的地方有D个;
求D个城市中距离草儿家最近的距离。
s.进行1次单源最短路,找出距离最小的即可。
c.Dijkstra单源最短路
- /*
- Dijkstra单源最短路
- 权值必须是非负
- 单源最短路径,Dijkstra算法,邻接矩阵形式,复杂度为O(n^2)
- 求出源beg到所有点的最短路径,传入图的顶点数,和邻接矩阵cost[][]
- 返回各点的最短路径lowcost[],路径pre[].pre[i]记录beg到i路径上的父结点,pre[beg]=-1
- 可更改路径权类型,但是权值必须为非负
- */
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- using namespace std;
- const int MAXN=;
- #define typec int
- const typec INF=0x3f3f3f3f;//防止后面溢出,这个不能太大
- bool vis[MAXN];
- int pre[MAXN];
- void Dijkstra(typec cost[][MAXN],typec lowcost[],int n,int beg){
- for(int i=;i<n;i++){
- lowcost[i]=INF;vis[i]=false;pre[i]=-;
- }
- lowcost[beg]=;
- for(int j=;j<n;j++){
- int k=-;
- int Min=INF;
- for(int i=;i<n;i++)
- if(!vis[i]&&lowcost[i]<Min){
- Min=lowcost[i];
- k=i;
- }
- if(k==-)break;
- vis[k]=true;
- for(int i=;i<n;i++)
- if(!vis[i]&&lowcost[k]+cost[k][i]<lowcost[i]){
- lowcost[i]=lowcost[k]+cost[k][i];
- pre[i]=k;
- }
- }
- }
- int cost[MAXN][MAXN];
- int lowcost[MAXN];
- int main(){
- int T,S,D;
- int a,b,time;
- int city1[MAXN];
- int city2[MAXN];
- while(~scanf("%d%d%d",&T,&S,&D)){
- for(int i=;i<MAXN;++i){
- for(int j=;j<MAXN;++j){
- cost[i][j]=INF;
- }
- }
- memset(vis,false,sizeof(vis));
- for(int i=;i<T;++i){
- scanf("%d%d%d",&a,&b,&time);
- if(time<cost[a][b]){
- cost[a][b]=time;
- cost[b][a]=time;
- }
- }
- //0作为草儿家
- for(int i=;i<S;++i){
- scanf("%d",&city1[i]);
- cost[][city1[i]]=;
- cost[city1[i]][]=;
- }
- for(int i=;i<D;++i){
- scanf("%d",&city2[i]);
- }
- Dijkstra(cost,lowcost,MAXN,);
- int minTime=lowcost[city2[]];
- for(int i=;i<D;++i){
- if(lowcost[city2[i]]<minTime)
- minTime=lowcost[city2[i]];
- }
- printf("%d\n",minTime);
- }
- return ;
- }
c2.Dijkstra算法+堆优化
- /*
- Dijkstra算法+堆优化
- 使用优先队列优化,复杂度O(E log E)
- 使用优先队列优化Dijkstra算法
- 复杂度O(E log E)
- 注意对vector<Edge>E[MAXN]进行初始化后加边
- */
- #include<iostream>
- #include<stdio.h>
- #include<vector>
- #include<string.h>
- #include<queue>
- using namespace std;
- const int INF=0x3f3f3f3f;
- const int MAXN=;
- struct qnode{
- int v;
- int c;
- qnode(int _v=,int _c=):v(_v),c(_c){}
- bool operator <(const qnode &r)const{
- return c>r.c;
- }
- };
- struct Edge{
- int v,cost;
- Edge(int _v=,int _cost=):v(_v),cost(_cost){}
- };
- vector<Edge>E[MAXN];
- bool vis[MAXN];
- int dist[MAXN];
- //点的编号从1开始
- void Dijkstra(int n,int start){
- memset(vis,false,sizeof(vis));
- for(int i=;i<=n;i++)dist[i]=INF;
- priority_queue<qnode>que;
- while(!que.empty())que.pop();
- dist[start]=;
- que.push(qnode(start,));
- qnode tmp;
- while(!que.empty()){
- tmp=que.top();
- que.pop();
- int u=tmp.v;
- if(vis[u])continue;
- vis[u]=true;
- for(int i=;i<E[u].size();i++){
- int v=E[tmp.v][i].v;
- int cost=E[u][i].cost;
- if(!vis[v]&&dist[v]>dist[u]+cost){
- dist[v]=dist[u]+cost;
- que.push(qnode(v,dist[v]));
- }
- }
- }
- }
- void addedge(int u,int v,int w){
- E[u].push_back(Edge(v,w));
- }
- int main(){
- int T,S,D;
- int a,b,time;
- int city1[MAXN];
- int city2[MAXN];
- while(~scanf("%d%d%d",&T,&S,&D)){
- for(int i=;i<MAXN;++i){
- E[i].clear();
- }
- for(int i=;i<T;++i){
- scanf("%d%d%d",&a,&b,&time);
- addedge(a,b,time);//这里有重边了。。没办法,
- addedge(b,a,time);
- }
- //0作为草儿家
- for(int i=;i<S;++i){
- scanf("%d",&city1[i]);
- addedge(,city1[i],);
- addedge(city1[i],,);
- }
- for(int i=;i<D;++i){
- scanf("%d",&city2[i]);
- }
- Dijkstra(MAXN-,);
- int minTime=dist[city2[]];
- for(int i=;i<D;++i){
- if(dist[city2[i]]<minTime)
- minTime=dist[city2[i]];
- }
- printf("%d\n",minTime);
- }
- return ;
- }
c3.单源最短路bellman_ford算法
- /*
- 单源最短路bellman_ford算法
- 单源最短khtkbellman_ford算法,复杂度O(VE)
- 可以处理负边权图。
- 可以判断是否存在负环回路。返回true,当且仅当图中不包含从源点可达的负权回路
- vector<Edge>E;先E.clear()初始化,然后加入所有边
- 点的编号从1开始(从0开始简单修改就可以了)
- */
- #include<iostream>
- #include<stdio.h>
- #include<vector>
- using namespace std;
- const int INF=0x3f3f3f3f;
- const int MAXN=;
- int dist[MAXN];
- struct Edge{
- int u,v;
- int cost;
- Edge(int _u=,int _v=,int _cost=):u(_u),v(_v),cost(_cost){}
- };
- vector<Edge>E;
- //点的编号从1开始
- bool bellman_ford(int start,int n){
- for(int i=;i<=n;i++)dist[i]=INF;
- dist[start]=;
- //最多做n-1次
- for(int i=;i<n;i++){
- bool flag=false;
- for(int j=;j<E.size();j++){
- int u=E[j].u;
- int v=E[j].v;
- int cost=E[j].cost;
- if(dist[v]>dist[u]+cost){
- dist[v]=dist[u]+cost;
- flag=true;
- }
- }
- if(!flag)return true;//没有负环回路
- }
- for(int j=;j<E.size();j++)
- if(dist[E[j].v]>dist[E[j].u]+E[j].cost)
- return false;//有负环回路
- return true;//没有负环回路
- }
- void addedge(int u,int v,int cost){
- E.push_back(Edge(u,v,cost));
- }
- int main(){
- int T,S,D;
- int a,b,time;
- int city1[MAXN];
- int city2[MAXN];
- while(~scanf("%d%d%d",&T,&S,&D)){
- E.clear();
- for(int i=;i<T;++i){
- scanf("%d%d%d",&a,&b,&time);
- addedge(a,b,time);//有重边了。
- addedge(b,a,time);
- }
- //0作为草儿家
- for(int i=;i<S;++i){
- scanf("%d",&city1[i]);
- addedge(,city1[i],);
- addedge(city1[i],,);
- }
- for(int i=;i<D;++i){
- scanf("%d",&city2[i]);
- }
- bellman_ford(,MAXN-);//MAXN-1
- int minTime=dist[city2[]];
- for(int i=;i<D;++i){
- if(dist[city2[i]]<minTime)
- minTime=dist[city2[i]];
- }
- printf("%d\n",minTime);
- }
- return ;
- }
c4.单源最短路SPFA
- /*
- 单源最短路SPFA
- 时间复杂度O(kE)
- 这个是队列实现,有时候改成栈实现会更加快,很容易修改
- 这个复杂度是不定的
- */
- #include<iostream>
- #include<stdio.h>
- #include<vector>
- #include<string.h>
- #include<queue>
- using namespace std;
- const int MAXN=;
- const int INF=0x3f3f3f3f;
- struct Edge{
- int v;
- int cost;
- Edge(int _v=,int _cost=):v(_v),cost(_cost){}
- };
- vector<Edge>E[MAXN];
- void addedge(int u,int v,int w){
- E[u].push_back(Edge(v,w));
- }
- bool vis[MAXN];//在队列标志
- int cnt[MAXN];//每个点的入队列次数
- int dist[MAXN];
- bool SPFA(int start,int n){
- memset(vis,false,sizeof(vis));
- for(int i=;i<=n;i++)dist[i]=INF;
- vis[start]=true;
- dist[start]=;
- queue<int>que;
- while(!que.empty())que.pop();
- que.push(start);
- memset(cnt,,sizeof(cnt));
- cnt[start]=;
- while(!que.empty()){
- int u=que.front();
- que.pop();
- vis[u]=false;
- for(int i=;i<E[u].size();i++){
- int v=E[u][i].v;
- if(dist[v]>dist[u]+E[u][i].cost){
- dist[v]=dist[u]+E[u][i].cost;
- if(!vis[v]){
- vis[v]=true;
- que.push(v);
- if(++cnt[v]>n)return false;
- //cnt[i] 为入队列次数,用来判定是否存在负环回路
- }
- }
- }
- }
- return true;
- }
- int main(){
- int T,S,D;
- int a,b,time;
- int city1[MAXN];
- int city2[MAXN];
- while(~scanf("%d%d%d",&T,&S,&D)){
- for(int i=;i<MAXN;++i){
- E[i].clear();
- }
- for(int i=;i<T;++i){
- scanf("%d%d%d",&a,&b,&time);
- addedge(a,b,time);//有重边了。
- addedge(b,a,time);
- }
- //0作为草儿家
- for(int i=;i<S;++i){
- scanf("%d",&city1[i]);
- addedge(,city1[i],);
- addedge(city1[i],,);
- }
- for(int i=;i<D;++i){
- scanf("%d",&city2[i]);
- }
- SPFA(,MAXN-);//MAXN-1
- int minTime=dist[city2[]];
- for(int i=;i<D;++i){
- if(dist[city2[i]]<minTime)
- minTime=dist[city2[i]];
- }
- printf("%d\n",minTime);
- }
- return ;
- }
增加一个Floyd的邻接表(这个题不错,有时间看看)
http://blog.163.com/zjut_nizhenyang/blog/static/169570029201111841938607/
Floyd
http://www.cnblogs.com/zswbky/p/5432387.html
最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)的更多相关文章
- 【算法】单源最短路——Dijkstra
对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...
- [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)
Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...
- 单源最短路模板(dijkstra)
单源最短路(dijkstra算法及堆优化) 弱化版题目链接 n^2 dijkstra模板 #include<iostream> #include<cstdio> #includ ...
- 单源最短路——dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...
- 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home
https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...
- 利用分支限界法求解单源最短路(Dijkstra)问题
分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...
- 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)
题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...
- 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)
题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...
- 模板C++ 03图论算法 1最短路之单源最短路(SPFA)
3.1最短路之单源最短路(SPFA) 松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离. 邻接表:表示与一个点联通的所有路. 如果从一个点沿着某条路径出发,又回到了自己,而且所经过 ...
随机推荐
- RBM阅读笔记
RBM包含两个层,可见层(visble layer)和隐藏层(hidden layer).神经元之间的连接具有以下特点:层内无连接,层间全连接.RBM可以看做是一个二分图(神经元当做顶点,神经元之间的 ...
- 移动端的拖拽这个demo实现的功能
SQL数据库适合那些需求确定和对数据完整性要去严格的项目.NoSQL数据库适用于那些对速度和可扩展性比较看重的那些不相关的,不确定和不断发展的需求. 总所周知,网页的加载速度跟图片是有很大的关系的,因 ...
- SQL EXEC 命令用法
EXEC命令有两个用法: 1.执行一个存储过程,或者执行一个动态批次. 2.批次是一个内容为SQL语句的字符串. 举列子: 1.exec name_proc :没有参数 exec name_proc ...
- opendir函数
#include<sys/types.h> #include<dirent.h> DIR *dirptr = NULL; struct dirent *entry; dirpt ...
- 【python】PIL 批量绘制图片矩形框工具
工具采用PIL:Python Imaging Library,图像处理标准库.PIL功能非常强大,但API却非常简单易用. 安装PIL 在Debian/Ubuntu Linux下直接通过apt安装 $ ...
- MySql分组函数-Group by与having理解
注意:select 后的字段,必须要么包含在group by中,要么包含在having 后的聚合函数里. 1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用 group ...
- POI2012
现在才开始写 POI 是不是太弱了? -Rendezvous 怎么说呢,我发现我的代码好长啊-长啊-长啊-长长长长长长长长长长长长长长长长长长长长长长啊- 大概就是在一个内向树上搞一个类似 lca 的 ...
- [转]使用Maven添加依赖项时(Add Dependency)时,没有提示项目可用,并且在Console中,输出: Unable to update index for central|http://repo1.maven.org/maven2 。
使用Maven添加依赖项时(Add Dependency)时,没有提示项目可用,并且在Console中,输出: Unable to update index for central|http://re ...
- [原创]cocos2d-x研习录-第三阶 特性之调度器
在游戏中,经常会周期执行一些检测.操作或更新一些数据等,我们称之为调度.Cocos2D-x中将调度封装为类CCScheduler,方便在游戏开发中使用.我们一起来学习一下,CCScheduler具有哪 ...
- logrotate机制与原理[转载]
http://blog.lightxue.com/how-logrotate-works/ 日志实在是太有用了,它记录了程序运行时各种信息.通过日志可以分析用户行为,记录运行轨迹,查找程序问题.可惜磁 ...