MST:Roadblocks(POJ 3255)
题目大意:某个街区有R条路,N个路口,道路双向,问你从开始(1)到N路口的次短路经长度,同一条边可以经过多次。
这一题相当有意思,现在不是要你找最短路径,而是要你找次短路经,而且次短路经同一条可以经过多次,用Dijkstra的方法最短路是只会经过一条边的。
但是别急,我们次短路经也是建立在最短路径上的,那么其实我们完全可以用最短路径的算法来解决这个问题,但是要修改一下算法,这里用Dijkstra算法(没有负边),我们设定两个区域,一个是最短路径区域,一个是次短路径区域,问题来了,怎么更新这两个区域呢?
首先最短路径区域更新的方法是一样的,次短路经怎么办?我们可以根据次短路经是上一条最短路径+本次路径次短边来完成这个操作,但是上一次最短路径可以是多条,所以我们就要想想办法了,其实在这里我们可以把以前我们熟悉的Dijkstra算法的known域去掉,那样我们就可以不用受“节点只能经过一次”的限制了,而且也实现了一条边可以经过多次,而且我们会把节点多次入堆,节点不再是纯粹的单节点了,而是一个临时节点(即最短路径和次短路经都是临时的,但是我们只用维护最短的就可以了),实现对路径的选择(而不是节点)
那么更新的时候我们围绕次短路经来裁剪选择就可以了,当目标节点的当前次短路经比临时的最短路径还要大,那就不必搜索了。
所以这题千万不能用以前那个旧方法,我就生搬硬套,没有考虑到次短路经不能第一时间维护,所以导致多次wa,心疼
#include <iostream>
#include <functional>
#include <algorithm>
#include <queue>
#define MAX 5004
#define MAX_E 100005 using namespace std;
typedef int Position; typedef struct map//向前边方法储存邻接表
{
int cost;
Position to;
int next; }Edge;
typedef struct node_
{
Position point;
Position v;
int cost;//最短路径
bool operator<(const node_ &x)const
{
return cost > x.cost;
} }Node; static Edge edge[MAX_E * ];
static Node head[MAX];
static int Dist_Min[MAX], Dist_last_min[MAX]; void Dijkstra(const int);
void Swap(int *const, int *const); int main(void)
{
int Node_Sum, Road_Sum, from, to, tmp_cost;
while (~scanf("%d%d", &Node_Sum, &Road_Sum))
{ for (int i = ; i <= Node_Sum; i++)
{
head[i].v = i;
head[i].point = -;
}
for (int i = ; i < Road_Sum * ; i += )//向前边法储存邻接表
{
scanf("%d%d%d", &from, &to, &tmp_cost); edge[i].next = head[from].point; edge[i].to = to; edge[i].cost = tmp_cost;
head[from].point = i;
edge[i + ].next = head[to].point; edge[i + ].to = from; edge[i + ].cost = tmp_cost;
head[to].point = i + ;
}
Dijkstra(Node_Sum);
}
return ;
} void Swap(int *const a, int *const b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
} void Dijkstra(const int Node_Sum)
{
int out, v, k, dist, d_out;
Edge e_tmp; Node Node_tmp; fill(Dist_last_min + , Dist_last_min + Node_Sum + , 0x7fffffff);
fill(Dist_Min + , Dist_Min + Node_Sum + , 0x7fffffff); priority_queue<Node> que;
Dist_Min[] = ;
Node_tmp.v = ; Node_tmp.cost = ; Node_tmp.point = head[].point;
que.push(Node_tmp); while (!que.empty())//Diskstra算法还可以找次短路
{
Node_tmp = que.top(); que.pop(); out = Node_tmp.v; d_out = Node_tmp.cost;
if (d_out > Dist_last_min[out]) continue;//千万不要简单的就直接用以前的方法固定min_dist,因为
for (k = Node_tmp.point; k != -; k = edge[k].next)
{
e_tmp = edge[k]; v = e_tmp.to;
dist = d_out + e_tmp.cost;
if (dist < Dist_Min[v])
{
Swap(&dist, &Dist_Min[v]);//注意一定是交换!
Node_tmp.v = v; Node_tmp.cost = Dist_Min[v]; Node_tmp.point = head[v].point;
que.push(Node_tmp);
}
if (dist < Dist_last_min[v] && dist > Dist_Min[v])
{
Dist_last_min[v] = dist;
Node_tmp.v = v; Node_tmp.cost = Dist_last_min[v]; Node_tmp.point = head[v].point;
que.push(Node_tmp);//这里会造成v多次入堆,需要做特判
}
}
}
printf("%d\n", Dist_last_min[Node_Sum]);
}

MST:Roadblocks(POJ 3255)的更多相关文章
- Roadblocks(POJ 3255)
原题如下: Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19314 Accepted: 6777 ...
- POJ 3255 Roadblocks(A*求次短路)
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12167 Accepted: 4300 Descr ...
- POJ 3255 Roadblocks (次级短路问题)
解决方案有许多美丽的地方.让我们跳回到到达终点跳回(例如有两点)....无论如何,这不是最短路,但它并不重要.算法能给出正确的结果 思考:而最短的路到同一点例程.spfa先正达恳求一次,求的最短路径的 ...
- POJ 3255 Roadblocks (次短路模板)
Roadblocks http://poj.org/problem?id=3255 Time Limit: 2000MS Memory Limit: 65536K Descriptio ...
- 次最短路径 POJ 3255 Roadblocks
http://poj.org/problem?id=3255 这道题还是有点难度 要对最短路径的算法非常的了解 明晰 那么做适当的修改 就可以 关键之处 次短的路径: 设u 到 v的边权重为cost ...
- poj 3255 Roadblocks
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13216 Accepted: 4660 Descripti ...
- poj 3255 Roadblocks 次短路(两次dijksta)
Roadblocks Time Limit : 4000/2000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total S ...
- POJ 3255 Roadblocks (Dijkstra求最短路径的变形)(Dijkstra求次短路径)
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16425 Accepted: 5797 Descr ...
- 【POJ - 3255】Roadblocks(次短路 Dijkstra算法)
Roadblocks 直接翻译了 Descriptions Bessie搬到了一个新的农场,有时候他会回去看他的老朋友.但是他不想很快的回去,他喜欢欣赏沿途的风景,所以他会选择次短路,因为她知道一定有 ...
随机推荐
- Ubuntu安装VMware Tools的方法
最后我将提供一个12版本的VMware Tools集合,包括了linux.iso. 背景: VMware Tools是VMware虚拟机中自带的一种增强工具,相当于VirtualBox中的增强功能(S ...
- Java 对象的串行化(Serialization)
1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力.叫作对象的持续性(pe ...
- windows搭建openacs编译环境
1.下载ant工具用来编译openacs源码 apache-ant-1.8.2 下载地址http://ant.apache.org/ 这个文件不用编译,在目录bin/下有针对windows的ant 2 ...
- Jsonp简单认识(后端使用的是asp.net mvc)
一.Jsonp简介:由于浏览器基于安全有同源策略(同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性)机制,所以前端无法使用Ajax来获取来获取其他域名下返回的数据,而Jsonp可 ...
- 织梦dedecms调用子栏目的方法
织梦调用子栏目名称在栏目.文章页及首页的方法是有区别的.首页的调用方法和在栏目的调用基本是一样的,如下: {dede:channel typeid=''} <li><h3>&l ...
- latex+bibtex+jabref(zz)
很好的的latex使用心得: bibtex现学现卖 http://derecks.blog.sohu.com/118984444.html latex+bibtex+jabref http://blo ...
- memcached安装和php-memcached扩展安装.update.2014-08-15
服务器端主要是安装memcache服务器端,目前的最新版本是 memcached-1.3.0 .下载官网:http://www.danga.com另外,Memcache用到了libevent这个库用于 ...
- juery动态添加和删除
拼语句添加框(不能删除原有的tr) //点击a标签 $("#a").on("click",function(){ var $newtr = $("&l ...
- derby数据库ql语法
[数据库知识] 主键.唯一键包含索引 主键包含唯一键.索引.非空 唯一键包含索引,可空或非空 数据库需要与执行服务的在同个目录下 唯一键 create table app.tyu ( primaryk ...
- 详述Linux ftp命令的使用方法
转自:http://os.51cto.com/art/201003/186325.htm ftp服务器在网上较为常见,Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件,这里 ...