补题(最短路+拆点)HUD-6805
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相关推荐
- 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)(补题记录)
一篇来自ACM入门者的补题记录 文章目录 A.机器人 B.吃豆豆 C.拆拆拆数 E.流流流动 F.爬爬爬山 I.起起落落 J.夺宝奇兵 A.机器人 题意:有两条平行线段A,B,长度从1~n,机器人一开 ...
- [题单]多校补题 2017-2012
仅做初步了解并筛除了不大可能会解的题目 (一般都会咕的) hard表示榜单过题人数少于50或20(大概)的题目 ****2017**** 6034 贪心 6035 树形DP OO 6038 组合数学 ...
- 2016ACM/ICPC亚洲区大连站-补题
2016ACM/ICPC亚洲区大连站-补题 5971-Wrestling Match 题目隐藏条件:除去已经知道的好人和坏人,如果剩余的人恰好被分成两组,即便不知道这两组哪组是好人,也是输出YES 做 ...
- 2019ICPC上海区域赛 补题(12/13) 总结
前言: 个人的 ICPCICPCICPC 第一站,还是值得记录一下的(虽然咕到现在才记录),总体而言体验很不错,比赛兼旅游.这套题总体印象就是树树树图,作为队里数据结构兼图论选手,这次也确实写了大部分 ...
- 2020牛客多校暑期训练营(赛后总结和补题)
https://ac.nowcoder.com/acm/contest/5668/B AC代码: #include <iostream> using namespace std; int ...
- 2019HDU多校补题
心得:做不出,补不动 HUD第一场: 1001 Blank Y 1002 Operation Y 1003 Milk 1004 Vication Y 1005 Path Y 1006 Typewrit ...
- 2019暑期多校补题情况 hdu
hdu: Ο 以补 . 未补 题号 A B C D E F G H I J K L 状态 . Ο . Ο Ο . . . . . . . 第一场: 现场: 1004:思路 1005:板子最短路+最 ...
- 2021年度训练联盟热身训练赛第三场赛后补题
2021年度训练联盟热身训练赛第三场赛后补题 A Circuit Math [题目分析] [代码展示] B Diagonal Cut [题目分析] [代码展示] C Gerrymandering [题 ...
- 南昌邀请赛 赛后总结与补题
以下所有代码为自己xjb写的,不确定对不对,如果有重现赛,可以交一交 后续:7月23号重现赛,都交了一下,发现都可以过,mdzz 本次邀请赛,说明我们队还是离邀请赛金或者区域赛稳银还是有很大的距离的, ...
- 八月十七日个人训练小结(补题)
前言 今天主要是补题,牛客,杭电和落下的cf 一.杭电补题 1.Shortest Path in GCD Graph 答案只有1和2,开始想用最短路,最后还是没能解决,这不是一个最短路问题,算是思维题 ...
最新文章
- Eureka restTemplate访问超时
- 「HDU6158」 The Designer(圆的反演)
- Microsoft 顺序分析和聚类分析算法
- POJ1151(矩形切割入门题)
- LiveVideoStack线上交流分享 (十一) —— B站Up主上传质量调优实践
- 谈谈对python 和其他语言的区别_谈谈Python和其他语言的区别
- pytorch 对抗样本_《AI安全之对抗样本入门》—3.4 PyTorch
- 让电脑说话代码_让您的代码为您说话
- nginx作用_云服务器:详解Nginx启用proxy_buffer缓冲
- 2021年中国电动气动控制器市场趋势报告、技术动态创新及2027年市场预测
- 【codevs2144】砝码称重 2(折半搜索)
- Educoder Basemap和seaborn 第三关:Basemap
- 桌面计算机图标名字变了,电脑桌面图标突然变成未知图标怎么回事
- SDelete v2.04安全地擦除磁盘未分配部分中存在的任何文件数据(包括已经删除或加密的文件)
- word页码怎么从指定页开始设置?
- JavaScript与C#互通的DES加解密算法
- 分享一个基于Vue的家谱图/组织结构图实现方案
- 怎样把d盘改成c盘!如何把收藏夹和桌面的路径设成D盘
- jdk1.8 stream() 把List <String>变成String
- CHAPTER 23 Question Answering