题意:

t组输入,给你n个点m条边。你需要输出从s点到t点的最短距离,然后是m条边,每条边输入信息为:

a,b,c 表示从a点到b点的一个无向边长度为c

每一个点会有一个属性L、R或M

如果a和b一个为L,另一个为R,那么a和b之间的距离要增加x,即变为x+c

其他情况权值还是c

题解:

我们可以注意到M类型的点是一个特殊点,无论是L类型还是R类型的点和它相连,它们的距离都不会增加x

那么我么可以把M类型的点拆成两个点,例如a点为M类型的点,那么我们可以把a点变为L类型的点,a+n点变为R类型的点

这个样子去构造一个图,然后如果起点s是一个M类型的点,我们就让起点s和s+n都和0号点连一条权值为0的无向边,然后以0为起点跑一边迪杰斯特拉

否则,就直接以s点为起点跑一边迪杰斯特拉

代码:

#include <stack>
#include <queue>
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int INF=0x3f3f3f3f;
ll n,m,v[maxn];
char f[maxn];
struct shudui
{
ll start,val;
bool operator < (const shudui y)const
{
return val>y.val;
}
} str1,str2;
priority_queue<shudui>r;
vector<shudui>w[maxn];
void JK(ll st)
{
memset(v,INF,sizeof(v));
v[st]=0;
str1.start=st;
str1.val=0;
r.push(str1);
while(!r.empty())
{
ll x,y;
str1=r.top();
r.pop();
x=str1.start;
y=str1.val;
if(v[x]<y) continue;
//说明在这个点再此之后又入队了
//此次出队的并不是s到这个点的最短路,
//所以在这次更新前点v所连的点已经更过一次了
//所以后面也不会进行松弛操作
ll len=w[x].size();
for(ll i=0;i<len;++i)
{
str2=w[x][i];
if((v[x]+str2.val<v[str2.start]))
{
v[str2.start]=v[x]+str2.val;
str1.start=str2.start;
str1.val=v[str2.start];
r.push(str1);
}
}
}
}
void add_edge(ll a,ll b,ll c)
{
str2.start=b;
str2.val=c;
w[a].push_back(str2);
str2.start=a;
w[b].push_back(str2);
} int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll s,t,x;
scanf("%lld%lld%lld%lld%lld",&n,&m,&s,&t,&x);
for(ll i=0;i<=2*n;++i)
w[i].clear();
scanf("%s",f+1);
while(m--)
{
ll a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
if(f[a]==f[b]&&(f[a]=='L'||f[b]=='R'))
{
add_edge(a,b,c);
}
else if(f[a]!=f[b]&&f[a]!='M'&&f[b]!='M')
{
add_edge(a,b,c+x);
}
else if(f[a]=='L'&&f[b]=='M')
{
add_edge(a,b,c);
add_edge(a,b+n,c+x);
}
else if(f[a]=='M'&&f[b]=='L')
{
add_edge(a,b,c);
add_edge(a+n,b,c+x);
}
else if(f[a]=='R'&&f[b]=='M')
{
add_edge(a,b,c+x);
add_edge(a,b+n,c);
}
else if(f[a]=='M'&&f[b]=='R')
{
add_edge(a+n,b,c);
add_edge(a,b,c+x);
}
else
{
add_edge(a,b,c);
add_edge(a,b+n,c+x);
add_edge(a+n,b,c+x);
add_edge(a+n,b+n,c);
}
}
ll ans=0;
if(f[s]=='M')
{
add_edge(0,s,0);
add_edge(0,s+n,0);
JK(0);
ans=min(v[t],v[t+n]);
}
else
{
JK(s);
//printf("%lld %lld \n",v[t],v[t+n]);
ans=min(v[t],v[t+n]);
}
printf("%lld\n",ans);
}
return 0;
}

迪杰斯特拉+拆点 Deliver the Cake - HDU 6805的更多相关文章

  1. C#迪杰斯特拉算法

    C#迪杰斯特拉算法 网上有许多版本的,自己还是写一个理解点 Dijkstra.cs public class Dijkstra { private List<Node> _nodes; p ...

  2. C++迪杰斯特拉算法求最短路径

    一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...

  3. 【算法杂谈】LJX的迪杰斯特拉算法报告

    迪杰斯特拉(di jie qi)算法 这里有一张图: 假设要求从1号节点到5号节点的最短路.那么根据迪杰斯特拉算法的思想,我们先看: 节点1,从节点1出发的一共有3条路,分别是1-6.1-3.1-2. ...

  4. C# 迪杰斯特拉算法 Dijkstra

    什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Gener ...

  5. 迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)

    迪杰斯特拉(dijkstra)算法:求最短路径的算法,数据结构课程中学习的内容. 1 . 理解 算法思想::设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合 ...

  6. 图-最短路径-Dijktra(迪杰斯特拉)算法

    1. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉算法于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始 ...

  7. 迪杰斯特拉算法——PAT 1003

    本文主要是将我对于我对于迪杰斯特拉算法的理解写出来,同时通过例题来希望能够加深对于算法的理解,其中有错误的地方希望大家指正. 迪杰斯特拉算法 我将这个算法理解成一个局部到整体的算法,这个方法确实越研究 ...

  8. 最短路径之迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉(Dijkstra)算法主要是针对没有负值的有向图,求解其中的单一起点到其他顶点的最短路径算法.本文主要总结迪杰斯特拉(Dijkstra)算法的原理和算法流程,最后通过程序实现在一个带权值的 ...

  9. 迪杰斯特拉(Java)

    public class Dijsktra { public static void main(String[] args) { Dijsktra d=new Dijsktra(); int[][] ...

随机推荐

  1. 【Redis3.0.x】实战案例

    Redis3.0.x 实战案例 简介 <Redis实战>的学习笔记和总结. 书籍链接 初识 Redis Redis 简介 Redis 是一个速度非常快的键值对存储数据库,它可以存储键和五种 ...

  2. 音视频入门-20-BMP、PNG、JPG、GIF静态图生成GIF动态图

    * 音视频入门文章目录 * 静态图 -> 动态图 前面 [18-手动生成一张GIF图片] 和 [19-使用giflib处理GIF图片] 生成的 GIF 每一帧都是一个颜色,平时用到的 GIF 每 ...

  3. 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)

    Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...

  4. 同一个网段内所有服务器virtual_router_id设置相同的后果

    /var/log/messages中一直报的错 one or more VIP associated with VRID mismatch actual MASTER advert bogus VRR ...

  5. 【ORA】ORA-4031错误分析和解决办法

    1. ORA-4031错误的原因,一般是大量的hard parse导致了shared pool中的free list中产生大量的内存小碎片,当一个需要很大内存来进行hard parse的sql语句到来 ...

  6. LeetCode671. 二叉树中第二小的节点

    题目 纯暴力 1 class Solution { 2 public: 3 vector<int>ans; 4 int findSecondMinimumValue(TreeNode* r ...

  7. window10系统安装

    准备工作: 一个U盘,大概8GB左右的存储,用于存放windows镜像文件与驱动精灵离线版网卡驱动以及相关的应用应用软件等. window10镜像文件(iso文件) 微PE工具软件 软件下载: 前提: ...

  8. Android事件分发机制三:事件分发工作流程

    前言 很高兴遇见你~ 本文是事件分发系列的第三篇. 在前两篇文章中,Android事件分发机制一:事件是如何到达activity的? 分析了事件分发的真正起点:viewRootImpl,Activit ...

  9. Java流程控制与Scanner类的使用

    Java流程控制与Scanner类的使用 Scanner类 Scanner类可以使程序接受键盘输入,实现人机交互 一个完整的Scanner的使用例子: //创建一个扫描器对象,用于接收键盘数据 Sca ...

  10. vue中computed/method/watch的区别

    摘要:本文通过官方文档结合源码来分析computed/method/watch的区别. Tips:本文分析的源码版本是v2.6.11,文章中牵涉到vue响应式系统原理部分,如果不是很了解,建议先阅读上 ...