bzoj 2069 [ POI 2004 ] ZAW —— 多起点最短路 + 二进制划分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2069
首先,对于和 1 相连的点,一定是从某个点出发,回到另一个点;
所以需要枚举起点和终点,但做 n 遍 dijkstra 不太可行;
可以进行多起点最短路,一次知道了以一些点作为起点、另一些点作为终点的答案;
于是问题是如何划分起点和终点,使一定能找到最优解;
二进制划分,枚举每一位,这一位是 0/1 分成两部分,那么任意不同的两个数一定某一次被分到了不同的集合;
具体做法可以是从 1 出发,不让起点回到 1,不让终点来到 1,最后看看终点的 dis;
也可以干脆去掉 1,起点的 dis 值是从 1 到它的距离;
注意分成两部分后要分别跑一遍是起点和终点的。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; int const maxn=5005,maxm=20005,inf=0x3f3f3f3f; int n,m,hd[maxn],ct,to[maxm],nxt[maxm],w[maxm],dis[maxn],mx,ans=inf; int son[maxn],ss,wt[maxn],wc[maxn]; bool vis[maxn],st[maxn],ed[maxn]; priority_queue<pair<int,int> >q; void add(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; w[ct]=z; hd[x]=ct;} void dijkstra() {while(q.size())q.pop();memset(vis,0,sizeof vis);memset(dis,0x3f,sizeof dis);dis[1]=0; q.push(make_pair(0,1)); // for(int i=1,x;i<=ss;i++) // if(st[x=son[i]])dis[x]=wt[x],q.push(make_pair(-dis[x],x)); // vis[1]=1;while(q.size()){int x=q.top().second; q.pop();if(vis[x])continue; vis[x]=1;for(int i=hd[x],u;i;i=nxt[i]){if(vis[u=to[i]]||st[x]&&u==1||x==1&&ed[u])continue; // if(vis[u=to[i]])continue;if(dis[u]>dis[x]+w[i])dis[u]=dis[x]+w[i],q.push(make_pair(-dis[u],u));}}for(int i=1,x;i<=ss;i++)if(ed[x=son[i]])ans=min(ans,dis[x]+wc[x]); } int main() {scanf("%d%d",&n,&m);int tmp=n; while(tmp)mx++,tmp/=2;for(int i=1,x,y,a,b;i<=m;i++){scanf("%d%d%d%d",&x,&y,&a,&b);add(x,y,a); add(y,x,b);if(x==1)son[++ss]=y,wt[y]=a,wc[y]=b;if(y==1)son[++ss]=x,wt[x]=b,wc[x]=a;}for(int i=0;i<mx;i++){memset(st,0,sizeof st);memset(ed,0,sizeof ed);for(int j=1;j<=ss;j++)if(son[j]&(1<<i))st[son[j]]=1;else ed[son[j]]=1;dijkstra();for(int j=1,x;j<=ss;j++)if(st[x=son[j]])st[x]=0,ed[x]=1;else if(ed[x])ed[x]=0,st[x]=1;dijkstra();}printf("%d\n",ans);return 0; }
转载于:https://www.cnblogs.com/Zinn/p/9489380.html
bzoj 2069 [ POI 2004 ] ZAW —— 多起点最短路 + 二进制划分相关推荐
- [POI 2004]ZAW
[POI 2004]ZAW Description 在 Byte 山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是 1号点.两个洞室要么就通过隧道连接起来,要么就经过若 ...
- bzoj 4398 福慧双修 —— 二进制分组+多起点最短路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 按二进制每一位是 0/1 把 1 号点的儿子分成两组,分别作为起点和终点跑多起点最短路 ...
- 【BZOJ2069】ZAW(POI2004)-最短路+二进制分组
测试地址:ZAW 题目大意: 给定一张边是双向的图,一条边走不同的方向可能代价不同,代价都非负,求从点111出发,不经过重复的点或边的最小回路.n≤5000,m≤10000n\le 5000,m\le ...
- BZOJ 2069: [POI2004]ZAW(Dijkstra + 二进制拆分)
题意 给定一个有 \(N\) 个点 \(M\) 条边的无向图, 每条无向边 最多只能经过一次 . 对于边 \((u, v)\) , 从 \(u\) 到 \(v\) 的代价为 \(a\) , 从 \(v ...
- BZOJ.2069.[POI2004]ZAW(最短路Dijkstra 按位划分)
题目链接 \(Description\) 给定一张带权图(边是双向的,但不同方向长度不同).求从1出发,至少经过除1外的一个点,再回到1的最短路.点和边不能重复经过. \(n\leq5000,m\le ...
- BZOJ 2069 POI2004 ZAW 堆优化Dijkstra
题目大意:给定一张无向图,每条边从两个方向走各有一个权值,求从点1往出走至少一步之后回到点1且不经过一条边多次的最短路 显然我们需要从点1出发走到某个和点1相邻的点上,然后沿最短路走到另一个和点1相邻 ...
- 【刷题】BZOJ 2069 [POI2004]ZAW
Description 在Byte山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是一条笔直通向"前面洞口"的道路. 隧道互相都不交叉(他们只在洞室相 ...
- [BZOJ 1124][POI 2008] 枪战 Maf
1124: [POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MB Submit: 659 Solved: 259 [Submit][Stat ...
- 解题:POI 2004 String
题面 首先我们要有一个明确的构造思路 对于非根节点,我们把子树连上来的线两两配对,这样如果它有奇数个子树就会剩一个,这时候把这根线传给父亲即可.对于根节点还是两两配对,但是注意如果它也有奇数个子树就不 ...
最新文章
- mysql中查询表格属性
- java里锛是什么意思,java实验总结
- js轮询导致服务器瘫痪_演进:Tengine 从 Web 代理服务器 到 分布式推送服务器
- 《程序是怎样跑起来的》第一章读后感
- 第五章 初始jQuery
- vue-cli脚手架的.babelrc文件
- 旅游捞金的六大方式,玩着把钱赚了
- 如何安装无签名认证的rpm包
- WPF-005:关于使用PageFunction导航中KeepAlive的使用
- ZooKeeper食谱(八)
- 2019中国基金业金融科技发展白皮书
- 数控机床通信协议汇总
- 第九届信号与图像处理国际学术研讨会(CSIP 2022)
- Google play上架被拒踩坑系列
- 夜神模拟器换完本机的ip连不上忘 fiddler也抓不到模拟器的包
- iMeta | 中农李季组揭示有机农业长期定位试验番茄微生物组结构
- 多任务学习——【ICML 2018】GradNorm
- 【RTX操作系统教程】第4章 RTX操作系统介绍
- PID循迹机器人及整定
- ios 11 屏幕适配问题!
热门文章
- 程序异常终止:Process finished with exit code -1073741819 (0xC0000005)
- Dubbo线程池问题思考Thread pool is EXHAUSTED!
- [激光原理与应用-25]:《激光原理与技术》-11- 激光产生技术-非线性技术之激光倍频、非线性晶体CLBO、BBO、LBO
- DialogFragment 白边去除
- vue中将水印加在页面的某一部分
- 5.2.6UART寄存器编程(下)
- 在瑞芯微ok3568平台利用python实现Can通讯
- php swoole 教程,PHP Swoole 基本使用
- OPENGL 半透明贴图
- 【DB宝14】在Docker中只需2步即可拥有Oracle 11g企业版环境(11.2.0.4)