题意:

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. 支持向量机(SVM)原理详解

    SVM简介 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机:SVM还包括核技巧, ...

  2. Java高并发与多线程(二)-----线程的实现方式

    今天,我们开始Java高并发与多线程的第二篇,线程的实现方式. 通常来讲,线程有三种基础实现方式,一种是继承Thread类,一种是实现Runnable接口,还有一种是实现Callable接口,当然,如 ...

  3. 【Python】在CentOS6.8中安装pip9.0.1和setuptools33.1

    wget https://bootstrap.pypa.io/ez_setup.py python ez_setup.py install --如果这个文件安装需要下载的文件无法下载的话,手动下载,放 ...

  4. linux命名小技巧(持续更新)

    一   向某个文件批量加入内容 1.1 向/etc/wxm文件添加一大段内容可以使用这个命令 [root@registry easyrsa3]# cat <<EOF >varsset ...

  5. 环境配置-Java-02-卸载

    1.卸载程序 在windows程序与功能中卸载Java相关的两个程序 2.删除环境变量 在windows环境变量中删除JAVA_HOME.CLASSPATH 以及 PATH中的两条路径 3.查看是否卸 ...

  6. SparkStreaming和Kafka基于Direct Approach如何管理offset实现exactly once

    在之前的文章<解析SparkStreaming和Kafka集成的两种方式>中已详细介绍SparkStreaming和Kafka集成主要有Receiver based Approach和Di ...

  7. Python小度

    这只是一个对话器!还不能听歌(反正我也没在UNIT平台配置听歌的功能)! 反正最近也不知怎么的,就想做一个AI对话器语音识别和语音输出都不要,input()和print()就行本来准备用小爱的,但要实 ...

  8. jackson学习之三:常用API操作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. 通过封装openpyxl模块实现自己的Excel操作类

    """ excel类封装需要提供以下功能: 1.选择表单功能 2.读取一个单元格的数据功能 3.读取一行数据功能 4.读取表单中所有数据功能 5.往单元格中写入数据功能 ...

  10. How to Gracefully Close Channels

    小结: 1. When a goroutine sends a value to a channel, we can view the goroutine releases the ownership ...