迪杰斯特拉+拆点 Deliver the Cake - HDU 6805
题意:
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的更多相关文章
- C#迪杰斯特拉算法
C#迪杰斯特拉算法 网上有许多版本的,自己还是写一个理解点 Dijkstra.cs public class Dijkstra { private List<Node> _nodes; p ...
- C++迪杰斯特拉算法求最短路径
一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...
- 【算法杂谈】LJX的迪杰斯特拉算法报告
迪杰斯特拉(di jie qi)算法 这里有一张图: 假设要求从1号节点到5号节点的最短路.那么根据迪杰斯特拉算法的思想,我们先看: 节点1,从节点1出发的一共有3条路,分别是1-6.1-3.1-2. ...
- C# 迪杰斯特拉算法 Dijkstra
什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Gener ...
- 迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)
迪杰斯特拉(dijkstra)算法:求最短路径的算法,数据结构课程中学习的内容. 1 . 理解 算法思想::设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合 ...
- 图-最短路径-Dijktra(迪杰斯特拉)算法
1. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉算法于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始 ...
- 迪杰斯特拉算法——PAT 1003
本文主要是将我对于我对于迪杰斯特拉算法的理解写出来,同时通过例题来希望能够加深对于算法的理解,其中有错误的地方希望大家指正. 迪杰斯特拉算法 我将这个算法理解成一个局部到整体的算法,这个方法确实越研究 ...
- 最短路径之迪杰斯特拉(Dijkstra)算法
迪杰斯特拉(Dijkstra)算法主要是针对没有负值的有向图,求解其中的单一起点到其他顶点的最短路径算法.本文主要总结迪杰斯特拉(Dijkstra)算法的原理和算法流程,最后通过程序实现在一个带权值的 ...
- 迪杰斯特拉(Java)
public class Dijsktra { public static void main(String[] args) { Dijsktra d=new Dijsktra(); int[][] ...
随机推荐
- 剑指offer 查找和排序的基本操作:查找排序算法大集合
重点 查找算法着重掌握:顺序查找.二分查找.哈希表查找.二叉排序树查找. 排序算法着重掌握:冒泡排序.插入排序.归并排序.快速排序. 顺序查找 算法说明 顺序查找适合于存储结构为顺序存储或链接存储的线 ...
- Docker学习笔记之创建安装了nginx服务器的镜像
操作步骤: 1. 编辑Dockerfile 2. 使用build命令创建镜像 3. 使用run命令测试创建的镜像 编辑Dockerfile 首先,需要使用文本编辑器编辑Dockerfile文件(注意没 ...
- Nacos使用和注册部分源码介绍
Nacos简单介绍 Nacos致力于帮助您发现.配置和管理微服务.Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理.Nacos帮助您更敏捷和容易地构建. ...
- leetcode 864. 获取所有钥匙的最短路径(BFS,状态压缩)
题目链接 864. 获取所有钥匙的最短路径 题意 给定起点,要求在最短步骤内收集完所有钥匙,遇到每把锁之前只有 有对应的钥匙才能够打开 思路 BFS+状态压缩典型题目 先确定起点和总的钥匙数目,其次难 ...
- docker 运行时常见错误
docker 运行时常见错误 (1) Cannot connect to the Docker daemon at unix:///var/run/docker.sock. [root@localho ...
- JVM(四)打破双亲委派和SPI机制
前言: 我们都知道判断两个类是不是同一个,要根据类加载器和全限定名.这是为什么呢?为什么不同的类加载器加载同一个类是不同的呢? 答案就是,不同的类加载器所加载的类在方法区的存储空间是不同的即Insta ...
- kettle 连接oracle12c问题解决办法:
在oracle的安装文件目录......\NETWORK\ADMIN\sqlnet.ora 文件中添加该语句:SQLNET.ALLOWED_LOGON_VERSION_SERVER = 8window ...
- DDD领域驱动设计:仓储
1 前置阅读 在阅读本文章之前,你可以先阅读: 什么是DDD DDD的实体.值对象.聚合根的基类和接口:设计与实现 2 什么是仓储? 仓储封装了基础设施来提供查询和持久化聚合操作. 它们集中提供常见的 ...
- 使用Robo 3T操作MongoDB数据库
安装Robo 3T连接MongoDB数据库教程:https://blog.csdn.net/baidu_39298625/article/details/98845789 在IDEA中用三个jar包链 ...
- LOJ10163 Amount of Degrees
题目描述 求给定区间 [X,Y] 中满足下列条件的整数个数:这个数恰好等于 KK 个互不相等的 BB 的整数次幂之和.例如,设 X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意 输入格 ...