迪杰斯特拉+拆点 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[][] ...
随机推荐
- DTCC 2020 | 阿里云李飞飞:云原生分布式数据库与数据仓库系统点亮数据上云之路
简介: 数据库将面临怎样的变革?云原生数据库与数据仓库有哪些独特优势?在日前的 DTCC 2020大会上,阿里巴巴集团副总裁.阿里云数据库产品事业部总裁.ACM杰出科学家李飞飞就<云原生分布式数 ...
- 【分布式锁的演化】终章!手撸ZK分布式锁!
前言 这应该是分布式锁演化的最后一个章节了,相信很多小伙伴们看完这个章节之后在应对高并发的情况下,如何保证线程安全心里肯定也会有谱了.在实际的项目中也可以参考一下老猫的github上的例子,当然代码没 ...
- LeetCode543.二叉树的直径
题目 1 class Solution { 2 public: 3 int minimum = INT_MIN; 4 vector<int>res; 5 int diameterOfBin ...
- Electron实用技巧-开机启动时隐藏主窗口,只显示系统托盘
# 1 在桌面软件中,开机自启动是很常见的功能,在electron中也提供了很好的支持,以下是主要代码: //应用是否打包if (app.isPackaged) { //设置开机启动 app.se ...
- 基于kubernetes实现coredns的及验证
CoreDNS: k8s内部的DNS ,用于对pod对service做记录的,好让其他的pod做访问 这里不用做过多的阐述 官方kube-dns现在已经没有在维护了,从Kubernetes 1.11 ...
- linux中的虚拟环境工具
1.虚拟环境工具的学习 python的虚拟环境,其实就是在机器上,方便的创建出多个解释器,每个解释器运行一个项目,互相之间不受影响 2.virtualenv工具,可以方便的创建,使用,删除也很方便 3 ...
- django form和form组件
form介绍: 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是 ...
- centos7 centos-home 磁盘空间转移至centos-root下
亲测可用,转载是为了记录,方便下次自己查看,如后朋友看到,请去查看作者原文,支持原创!!! 原文连接:https://www.cnblogs.com/renshengruxi/p/11782980.h ...
- Netty服务端Server代码说明
本文是简单的Netty启动服务端代码理解笔记 public class MyServer { public static void main(String[] args) throws Excepti ...
- MySQL高可用HA——keepalived配置
0. Keepalived介绍 Keepalived是基于VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)协议的一款高可用软件.Keepaili ...