关于几个的区别和联系: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)的更多相关文章

  1. 【算法】单源最短路——Dijkstra

    对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...

  2. [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)

    Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...

  3. 单源最短路模板(dijkstra)

    单源最短路(dijkstra算法及堆优化) 弱化版题目链接 n^2 dijkstra模板 #include<iostream> #include<cstdio> #includ ...

  4. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  5. 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

    https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...

  6. 利用分支限界法求解单源最短路(Dijkstra)问题

    分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...

  7. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)

    题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...

  8. 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)

    题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...

  9. 模板C++ 03图论算法 1最短路之单源最短路(SPFA)

    3.1最短路之单源最短路(SPFA) 松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离. 邻接表:表示与一个点联通的所有路. 如果从一个点沿着某条路径出发,又回到了自己,而且所经过 ...

随机推荐

  1. safari 日期对象新建new Date( timeStr ) 参数TimeStr格式

    这是一个浏览器兼容的问题,在此总结一下,别老在这掉坑. 先坐下测试 var timeStrArray = [ '2016-10-04', '2016.10.04', '2016/10/04', '10 ...

  2. 关于URI URL URN

    刚琢磨.整理了关于escape.encodeURIComponent.encodeURI的知识.突然又对URI有点模糊了,遂整理了以下资源 : 资源一: URL,URI 和URN 的举例理解 资源二: ...

  3. 使用java连接sqlserver2008 R2/sqlserver2008

    package com.product.jdbc.dbutil; import java.sql.Connection;import java.sql.DriverManager;import jav ...

  4. jquery中的$的特殊用法

    通过父级元素选取子元素, $('父元素选择器,子元素选择器')        $('子元素选择器',父元素jquery对象); 通过$创建代码片段 $('<div/>',{ 'class' ...

  5. google gtest window 平台应用

    下载gtest:https://code.google.com/p/googletest/downloads/detail?name=gtest-1.7.0.zip 编译: 会出现的问题:error ...

  6. 《C与指针》第十四章练习

    本章问题 1.预处理器定义了5个符号,给出了进行编译的文件名.文件行的当前行号,当前日期和时间以及编译器是否为ANSI C编译器.为每个符号举出一种可能的用途. answer:在打印错误信息时,文件名 ...

  7. linq之将IEnumerable<T>类型的集合转换为DataTable类型 (转载)

    在考虑将表格数据导出成excel的时候,网上搜的时候找到一个特别合适的公共方法,可以将query查询出来的集合转换为datatable 需引用using System.Reflection; publ ...

  8. Android 的 DatePicker、TimePicker或NumberPicker

    布局文件加上这个就可以,去除日期选择器.时间选择器或数值选择器的可编辑状态. android:descendantFocusability="blocksDescendants" ...

  9. 安装dubbo-admin遇到的问题和解决之道

    这里不多说dubbo的相关知识.简单提示dubbo-admin所需的环境.java的jdk和jre,dubbo-admin.war,tomcat. 今天只是把在win7环境下安装了dubbo-admi ...

  10. Web性能测试的简介

    一.术语 1.并发用户:并发一般分两种.1)严格意义上的并发,即所有的用户在同一时刻做同一件事情或操作,这种操作一般指做同一类型的业务:2)广义范围的并发,与前者主要区别,尽管多个用户对系统发出了请求 ...