我简单的描述一下题目,题目中所说的有道路和航路:

1.公路是双向的,航路是单向的;

2.公路是正值,航路可正可负;

每一条公路i或者航路i表示成连接城镇Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代价为Ci;每一条公路,Ci的范围为0<=Ci<=10,000;

由于奇怪的运营策略,每一条航路的Ci可能为负的,也就是-10,000<=Ci<=10,000。

数据规模与约定

对于20%的数据,T<=100,R<=500,P<=500;

对于30%的数据,R<=1000,R<=10000,P<=3000;

对于100%的数据,1<=T<=25000,1<=R<=50000,1<=P<=50000。

输入格式

输入的第一行包含四个用空格隔开的整数T,R,P,S。(表示共有T个城镇,R条公路,P条航路,求S点到所有城镇的最短路)

接下来R行,描述公路信息,每行包含三个整数,分别表示Ai,Bi和Ci

接下来P行,描述航路信息,每行包含三个整数,分别表示Ai,Bi和Ci

输出格式
输出T行,分别表示从城镇S到每个城市的最小花费,如果到不了的话输出NO PATH。
样例输入
6 3 3 4
1 2 5
3 4 5
5 6 10
3 5 -100
4 6 -100
1 3 -10
样例输出
NO PATH
NO PATH
5
0
-95
-100
讲解:如果数据量比较少的话,很多方法都能做啦,什么Dijkstra,Bellman-ford,Floyd,都能简单的解决了,但是要想得满分,这道题目的数据量太大了,我直接套用的spfa   的模板直接过了,模板不错的,还能保存路径的;
 #include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int MAXN = ;
const int INF=0x7FFFFFFF;
struct edge
{
int to,weight;
};
int T,R,P,S;
vector<edge>adjmap[MAXN];//邻接表
bool in_queue[MAXN];//顶点是否在队列中
int in_sum[MAXN];//顶点入队的次数
int dist[MAXN];//源点到各点的最短路
int path[MAXN];//存储到达i的前一个顶点
int nodesum; //顶点数
int edgesum; //边数
bool spfa(int source)
{
deque< int > dq;
int i,j,x,to;
for(int i = ;i<=T;i++)//初始化函数
{
in_sum[i]= ;
in_queue[i]=false;
dist[i]=INF;
path[i]=-;
}
dq.push_back(source);
in_sum[source]++;
dist[source]=; //到达本身的最短距离为0
in_queue[source]= true;
while(!dq.empty())
{
x = dq.front();
dq.pop_front();
in_queue[x]=false;
for(int i = ;i<adjmap[x].size();i++)
{
to = adjmap[x][i].to;
if((dist[x]<INF) && ( dist[to]>dist[x]+adjmap[x][i].weight) )
{
dist[to] = dist[x]+adjmap[x][i].weight;
path[to] = x;
if(!in_queue[to])
{
in_queue[to] = true;
in_sum[to]++;
if(in_sum[to] == nodesum) return false;
if(!dq.empty())
{
if(dist[to]>dist[dq.front()]) dq.push_back(to);
else dq.push_front(to);
} else dq.push_back(to);
}
}
}
}
return true;
}
void print_path(int x)
{
//输出最小的花费
if(dist[x] == INF)//到不了的路径
cout<<"NO PATH"<<endl;
else cout<<dist[x]<<endl; // 下面是输出路径
// stack<int>s;
// int w = x;
// while(path[w]!=-1)
// {
// s.push(w);
// w=path[w];
// }
// //以下是经过的路径
// while(!s.empty())
// {
// cout<<s.top()<<" ";
// s.pop();
// }
// cout<<endl;
}
int main()
{ edge temp;
int s,e,w;
scanf("%d %d %d %d",&T,&R,&P,&S);
for(int i = ;i<T;i++)
adjmap[i].clear();//清空邻接表
for(int i = ; i<=R; i++)
{
scanf("%d %d %d",&s,&e,&w);
temp.to = e;
temp.weight = w;
adjmap[s].push_back(temp);
temp.to = s;
adjmap[e].push_back(temp);// 公路的是双向的,需要放入两次
}
for(int i = ;i<=P;i++)
{
scanf("%d %d %d",&s,&e,&w);
temp.to = e;
temp.weight = w;
adjmap[s].push_back(temp);
}
if(spfa(S))
{
for(int i =;i<=T; i++ )
print_path(i);
}
// else cout<<"图中存在负权回路"<<endl;
return ;
}

算法提高 道路和航路 SPFA 算法的更多相关文章

  1. 算法笔记_165:算法提高 道路和航路(Java)

    目录 1 问题描述 2解决方案   1 问题描述 问题描述 农夫约翰正在针对一个新区域的牛奶配送合同进行研究.他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条 ...

  2. Java实现 蓝桥杯 算法提高 道路和航路

    问题描述 农夫约翰正在针对一个新区域的牛奶配送合同进行研究.他打算分发牛奶到T个城镇(标号为1-T),这些城镇通过R条标号为(1-R)的道路和P条标号为(1-P)的航路相连. 每一条公路i或者航路i表 ...

  3. [hihoCoder] #1093 : 最短路径·三:SPFA算法

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋! 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之 ...

  4. 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题

    一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...

  5. SPFA算法学习笔记

    一.理论准备 为了学习网络流,先水一道spfa. SPFA算法是1994年西南交通大学段凡丁提出,只要最短路径存在,SPFA算法必定能求出最小值,SPFA对Bellman-Ford算法优化的关键之处在 ...

  6. 最短路径--SPFA 算法

    适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一 ...

  7. 算法提高 金属采集_树形dp

    算法提高 金属采集   时间限制:1.0s   内存限制:256.0MB        问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了.一些节点之间有道路相连 ...

  8. 算法笔记_166:算法提高 金属采集(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了.一些节点之间有道路相连,所有的节点和道路形成了一棵树.一共 ...

  9. 算法笔记_071:SPFA算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...

随机推荐

  1. 二十四种设计模式:建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...

  2. iOS: 使用故事板和xib设置按钮圆角方法

    使用storyboard如何设置圆角或边框? 通过storyboard的 运行时属性runtime attribute,可以对Button设置圆角或者边框 1.很多人都知道,通常设置一个 Button ...

  3. XSS攻击过滤函数

    黑客用XSS攻击有多种方式,PHP的内置函数不能应对各种各样的XSS攻击.因此,使用filter_var,mysql_real_escape_string,htmlentities,htmlspeci ...

  4. pyPdf - 用Python方便的处理PDF文档

    pyPdf库 ( http://pybrary.net/pyPdf/ ) ,操作起来相当直接易懂,把代码贴在这儿,做个记录.  1 from pyPdf import PdfFileWriter, P ...

  5. 让网页在ie浏览器下以最高版本解析网页

    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta ht ...

  6. 解析PHP中如何将数组变量写入文件

    在用PHP记录日志,或者是 Ajax 请求出错想要 debug 的时候.我们一般都会将信息写入到一个指定的文件当中.然后根据相应的信息来处理问题.比如笔者最喜欢在用 Ajax 取不到数据的时候,在PH ...

  7. RocketMQ概念整理

    DefaultMessageStore 消息的存储和提取. 相对重要的两个方法: 消息存储 PutMessageResult putMessage(MessageExtBrokerInner msg) ...

  8. css学习笔记 --初学 css代码风格、布局误区

    初学css,记录下初学者需要注意的事项. 一.css 代码风格 1.css 命名语义化. 如类名: main   主体   container 内容 footer    站底 right.center ...

  9. ios开发杂项(基础性介绍等)

    IOS Xcode开发中的文件后缀名区别m,mm,cpp,h .h :头文件.头文件包含类,类型,函数和常数的声明. .m :源代码文件.这是典型的源代码文件扩展名,可以包含Objective-C和C ...

  10. 《暗黑世界V1.3》数据库表说明文档

    <暗黑世界V1.3>数据库表说明文档 (下载地址:http://www.9miao.com/forum.php?mod=viewthread&tid=38821&highl ...