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

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. Quartz_TimeJob例子(C#)

    执行入口: using System; using System.Collections.Generic; using log4net; using Quartz; using ypt_base.Co ...

  2. [Java基础] Java enum的用法详解

    用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...

  3. java中jar命令打包一个文件夹下的所有文件

    (1)首先,必须保证java的所有路径都设置好,在dos提示符下输入jar -help出现C:\Documents and Settings\dly>jar -help非法选项:h用法:jar ...

  4. [Angular] Angular i18n Alternative Expressions Support (select)

    For example we have those code: <div class="course-category" [ngSwitch]="course.ca ...

  5. C# 5 in a Nutshell - Delegate

    1. What is delegate in C#? A delegate is an object that knows how to call a method.A delegate type d ...

  6. Android性能优化的方方面面

    通常项目比较大的APP都面临着如下性能问题,APP启动慢.界面跳转慢.事件相应慢.滑动和动画卡顿.展现内容慢等,有的公司处理的很好,有的还有很大的优化空间,对于性能优化,怎么去做,我总结了一下性能优化 ...

  7. 应用LR监控Apache性能

    1)对Apache服务器中的http.conf进行如下配置修改Apache中Httpd.conf文件,添加如下代码(该文件中都有,只要取消注释就好了)<Location /server-stat ...

  8. 关于comet

    Comet是彗星的意思,这一技术之所以借用这个名字,是因为这里的每一次请求都有一个长长的“尾巴”.这个长尾巴就是我们感兴趣的长连接. 因为长连接的实现,Comet可以不需要安装浏览器插件就可以向客户端 ...

  9. SVN:This client is too old to work with working copy…解决方法

    昨天升级了一下苹果系统到10.10,扁平化确实不错,高兴之余多少有些不快.我的svn出现故障,总是提示我  SVN:This client is too old to work with workin ...

  10. 在linux下的使用复制命令cp,不让出现“overwrite”(文件覆盖)提示的方法。(转)

    在linux下的使用复制命令cp,不让出现“overwrite”(文件覆盖)提示的方法. 一般我们在使用cp命令时加上-f选项,希望不让出现“overwrite”的提示(文件覆盖的提示).如:# cp ...