http://acm.hdu.edu.cn/showproblem.php?pid=6805
题意:有n个村庄,m条无向道路,道路单位为米,张三现在要拿着蛋糕从s村庄走到t村庄,村庄分为L M R三种类型。L村庄只能左手拿蛋糕,R村庄只能右手拿蛋糕,M村庄左右手拿都行,每次更换左右手必须停下耗费x秒的时间,现在要你求从s走到t的最短时间,速度看成1s/m。

刚开始思路:不考虑换手那就是最短路模板了,这题难点在于走的过程中不知道什么时候换手是最优解,我刚开始的做法是跑spfa,在更新路径的时候同时记录当前是哪只手提蛋糕(类似与bfs跑一个图时用结构体数组作队列记录路劲),TLE后就不知道怎么处理了

正解:将换手所耗费的时间转化为边权,只要将所有换手的情况都转化为边权,就不需要你考虑何时换手是最优解,跑一边dijs模板就行了
那怎么转化呢,我们先思考一条边上的两个点u和v有哪些组合情况,答案是3*3=9种(LL,LR,RL,RR,LM,ML,MR,RM,MM)前四种情况的边权是很好处理的,LL和RR正常连边,LR和RL就在u—v这条边权上加上x,
不好处理的是含M的情况,因为在前四种情况中你知道,当前不用换手(RR,LL),当前必须换手(LR,RL),但在含M时你不知道当前是否需要换手,不好处理M那就将M拆成L和R
拆点
将一个M点拆为一个R点和一个L点,例如LM这种情况就转化为了LL和LR这两种情况,RM就转化为RR和RL,MM则转化为RR,RL,LL,LR。转化后的连边情况都变成了上面好处理4种情况,然后就是跑dijs模板了。

代码:

#include<bits/stdc++.h>
using namespace std;
long long dis[1000005],vis[500005];//跑dijs的距离数组和标记数组struct my{int to;
long long cmp;//cmp是权值,rev记录to到from边在to表的位置
};
int n,m;//n个点m条边设为全局变量,其他设为局部变量(这样在多次跑dijs初始化时更不会出错)
int b[1000005];
char  c[1000005];
typedef pair<long long,int> P;//priority_queue<P,vector<P>,greater<P> > qque;
vector<my> e[500005];
void add_e(int from,int to,long long cmp)//加一条from到to权值为cmp的边,并且反向存to到from权值为0的边
{e[from].push_back((my){to,cmp});e[to].push_back((my){from,cmp});
}
void init()
{int N=2*n+5;for(int i=0;i<=N;i++){e[i].clear();b[i]=0;c[i]=0;dis[i]=0x3f3f3f3f3f3f3f3f;vis[i]=0;}// while(!qque.empty())//qque.pop();
}
void print(int s,int t,int x)
{int t1,t2;long long t3;scanf("%s",c);for(int i=0;i<n;i++){if(c[i]=='L')b[i+1]=1;else if(c[i]=='M')b[i+1]=2;else if(c[i]=='R') b[i+1]=3;}for(int i=0;i<m;i++){scanf("%d%d%lld",&t1,&t2,&t3);if(b[t1]==1&&b[t2]==3)add_e(t1,t2,t3+x);else if(b[t1]==3&&b[t2]==1)add_e(t1,t2,t3+x);else if(b[t1]==2&&b[t2]==1)add_e(t1,t2,t3),add_e(n+t1,t2,t3+x);else if(b[t2]==2&&b[t1]==1)add_e(t1,t2,t3),add_e(t1,n+t2,t3+x);else if(b[t1]==3&&b[t2]==2)add_e(t1,t2,t3+x),add_e(t1,n+t2,t3);else if(b[t1]==2&&b[t2]==3)add_e(t1,t2,t3+x),add_e(t1+n,t2,t3);else if(b[t1]==2&&b[t2]==2)add_e(t1,t2,t3),add_e(t1+n,t2+n,t3),add_e(t1,t2+n,t3+x),add_e(t1+n,t2,t3+x);else  if(b[t1]==1&&b[t2]==1)add_e(t1,t2,t3);else if(b[t1]==3&&b[t2]==3) add_e(t1,t2,t3);}
//if(b[s]==2)add_e(0,s+n,0),add_e(0,s,0);
//if(b[t]==2)add_e(2*n+1,n+t,0);add_e(2*n+1,t,0);
}void dij(int s,int t)
{priority_queue<P,vector<P>,greater<P> > qque;dis[s]=0;
qque.push(P(0,s));
int u,v,sizee;
long long ccmp;
while(!qque.empty()){P p=qque.top();u=p.second;qque.pop();//if(dis[u]<p.first) continue;//两种方式判断是否需要通过当前点去更新路径,这种方式可以省一个标记数组if(vis[u]==1) continue;//只通过每个点一次更新路径就行了,重复去更新可能会超时//if(u==t) break;//到通过t点更新时,已经找到了最小的dis【t】,可以提前结束vis[u]=1;sizee=e[u].size();for(int i=0;i<sizee;i++){v=e[u][i].to;ccmp=e[u][i].cmp;if(dis[v]>dis[u]+ccmp){dis[v]=dis[u]+ccmp;qque.push(P(dis[v],v));}}}}int main()
{int s,t,fre,x;cin>>fre;while(fre--){scanf("%d%d%d%d%d",&n,&m,&s,&t,&x);init();//初始化print(s,t,x);//输入边(建图)dij(0,2*n+1);//传入源点和汇点printf("%lld\n",dis[2*n+1]);}
}

补题(最短路+拆点)HUD-6805相关推荐

  1. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)(补题记录)

    一篇来自ACM入门者的补题记录 文章目录 A.机器人 B.吃豆豆 C.拆拆拆数 E.流流流动 F.爬爬爬山 I.起起落落 J.夺宝奇兵 A.机器人 题意:有两条平行线段A,B,长度从1~n,机器人一开 ...

  2. [题单]多校补题 2017-2012

    仅做初步了解并筛除了不大可能会解的题目 (一般都会咕的) hard表示榜单过题人数少于50或20(大概)的题目 ****2017**** 6034 贪心 6035 树形DP OO 6038 组合数学 ...

  3. 2016ACM/ICPC亚洲区大连站-补题

    2016ACM/ICPC亚洲区大连站-补题 5971-Wrestling Match 题目隐藏条件:除去已经知道的好人和坏人,如果剩余的人恰好被分成两组,即便不知道这两组哪组是好人,也是输出YES 做 ...

  4. 2019ICPC上海区域赛 补题(12/13) 总结

    前言: 个人的 ICPCICPCICPC 第一站,还是值得记录一下的(虽然咕到现在才记录),总体而言体验很不错,比赛兼旅游.这套题总体印象就是树树树图,作为队里数据结构兼图论选手,这次也确实写了大部分 ...

  5. 2020牛客多校暑期训练营(赛后总结和补题)

    https://ac.nowcoder.com/acm/contest/5668/B AC代码: #include <iostream> using namespace std; int ...

  6. 2019HDU多校补题

    心得:做不出,补不动 HUD第一场: 1001 Blank Y 1002 Operation Y 1003 Milk 1004 Vication Y 1005 Path Y 1006 Typewrit ...

  7. 2019暑期多校补题情况 hdu

    hdu: Ο 以补 .   未补 题号 A B C D E F G H I J K L 状态 . Ο . Ο Ο . . . . . . . 第一场: 现场: 1004:思路 1005:板子最短路+最 ...

  8. 2021年度训练联盟热身训练赛第三场赛后补题

    2021年度训练联盟热身训练赛第三场赛后补题 A Circuit Math [题目分析] [代码展示] B Diagonal Cut [题目分析] [代码展示] C Gerrymandering [题 ...

  9. 南昌邀请赛 赛后总结与补题

    以下所有代码为自己xjb写的,不确定对不对,如果有重现赛,可以交一交 后续:7月23号重现赛,都交了一下,发现都可以过,mdzz 本次邀请赛,说明我们队还是离邀请赛金或者区域赛稳银还是有很大的距离的, ...

  10. 八月十七日个人训练小结(补题)

    前言 今天主要是补题,牛客,杭电和落下的cf 一.杭电补题 1.Shortest Path in GCD Graph 答案只有1和2,开始想用最短路,最后还是没能解决,这不是一个最短路问题,算是思维题 ...

最新文章

  1. Eureka restTemplate访问超时
  2. 「HDU6158」 The Designer(圆的反演)
  3. Microsoft 顺序分析和聚类分析算法
  4. POJ1151(矩形切割入门题)
  5. LiveVideoStack线上交流分享 (十一) —— B站Up主上传质量调优实践
  6. 谈谈对python 和其他语言的区别_谈谈Python和其他语言的区别
  7. pytorch 对抗样本_《AI安全之对抗样本入门》—3.4 PyTorch
  8. 让电脑说话代码_让您的代码为您说话
  9. nginx作用_云服务器:详解Nginx启用proxy_buffer缓冲
  10. 2021年中国电动气动控制器市场趋势报告、技术动态创新及2027年市场预测
  11. 【codevs2144】砝码称重 2(折半搜索)
  12. Educoder Basemap和seaborn 第三关:Basemap
  13. 桌面计算机图标名字变了,电脑桌面图标突然变成未知图标怎么回事
  14. SDelete v2.04安全地擦除磁盘未分配部分中存在的任何文件数据(包括已经删除或加密的文件)
  15. word页码怎么从指定页开始设置?
  16. JavaScript与C#互通的DES加解密算法
  17. 分享一个基于Vue的家谱图/组织结构图实现方案
  18. 怎样把d盘改成c盘!如何把收藏夹和桌面的路径设成D盘
  19. jdk1.8 stream() 把List <String>变成String
  20. CHAPTER 23 Question Answering

热门文章

  1. [机器学习算法]机泊松回归算法原理详解和应用
  2. 小觅S系列相机运行VINS-Mono记录
  3. 高质量c++/c编程指南pdf
  4. laravel-admin码的开源B2B电子商务行业门户网站后台系统
  5. 对 FaaS 的基础认识
  6. java获取两个集合的交集,并集,差集,去重复并集
  7. c语言保留字(关键字)汇总
  8. Linux的super super super super easy教程 || 基本命令3
  9. Zabbix5.0 监控mysql
  10. 美元汇率问题 酒馆浪人的博客