题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398

按二进制每一位是 0/1 把 1 号点的儿子分成两组,分别作为起点和终点跑多起点最短路,最优解的起点和终点总有一次会被分到不同组里;

太久没写 dijkstra 竟然WA了4次...别忘了 priority_queue 是大根堆-_-,还要注意循环计数的 i,j 不要重了...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=40005,xm=1e5+5,inf=0x3f3f3f3f;
int n,m,hd[xn],ct,nxt[xm<<1],to[xm<<1],w[xm<<1],dis[xn],ans;
bool vis[xn],in[xn],out[xn];
struct N{int d,id;bool operator < (const N &y) const{return d>y.d;}//>
};
priority_queue<N>q;
int rd()
{int ret=0,f=1; char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();return f?ret:-ret;
}
void add(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; w[ct]=z; hd[x]=ct;}
void dij()
{memset(vis,0,sizeof vis);while(q.size()){int x=q.top().id; q.pop();if(vis[x])continue; vis[x]=1;for(int i=hd[x],u;i;i=nxt[i]){if(vis[u=to[i]]||(u==1&&out[x])||(x==1&&in[u]))continue;if(dis[u]>dis[x]+w[i])dis[u]=dis[x]+w[i],q.push((N){dis[u],u});}}ans=min(ans,dis[1]);
}
int main()
{n=rd(); m=rd();for(int i=1,x,y,z,k;i<=m;i++){x=rd(); y=rd(); z=rd(); k=rd();add(x,y,z); add(y,x,k);}int cnt=0,t=n; while(t)cnt++,t/=2; ans=inf;for(int i=0;i<cnt;i++){memset(dis,0x3f,sizeof dis); while(q.size())q.pop();for(int j=hd[1],u;j;j=nxt[j]){in[u=to[j]]=0; out[u]=0;if(u&(1<<i))dis[u]=w[j],out[u]=1,q.push((N){w[j],u});else in[u]=1;}      dij(); memset(dis,0x3f,sizeof dis); while(q.size())q.pop();for(int j=hd[1],u;j;j=nxt[j]){if(in[u=to[j]])in[u]=0,out[u]=1,dis[u]=w[j],q.push((N){w[j],u});else out[u]=0,in[u]=1;}dij(); }printf("%d\n",(ans==inf?-1:ans));return 0;
}

转载于:https://www.cnblogs.com/Zinn/p/9801811.html

bzoj 4398 福慧双修 —— 二进制分组+多起点最短路相关推荐

  1. bzoj 4398 福慧双修——二进制分组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. ...

  2. bzoj 2069 [ POI 2004 ] ZAW —— 多起点最短路 + 二进制划分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2069 首先,对于和 1 相连的点,一定是从某个点出发,回到另一个点: 所以需要枚举起点和终点 ...

  3. BZOJ 2407: 探险/BZOJ 4398: 福慧双修 dijkstra 构造

    2407: 探险 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 170  Solved: 95 [Submit][Status][Discuss] ...

  4. bzoj 4398 福慧双修 题解

    卡了一晚上啊 首先我们要跑一边整张图的spfa,记录每个点是从哪条边出去的(pre数组) 这里记录的不是前驱边,而是和原点相连的第一个点编号,因为不能走重复边所以才要记录这个,以免刚刚出去又原路返回 ...

  5. bzoj 4398: 福慧双修(最短路建模/构造)

    简述题意: 给定一个有向图,对于连接同两个点的边算作同一条,问不经过重复边的最小正权环. 保证没有重边(这个是指有向的),没有自环. 算法:最短路+构造 难度:NOIP+ 题解: 有一种暴力的思路,感 ...

  6. 【技巧 二进制分组】bzoj4398: 福慧双修2407: 探险

    二进制分组也可以说是一种比较优美的拆贡献方式吧? Description 菩萨为行,福慧双修,智人得果,不忘其本. --唐朠立<大慈恩寺三藏法师传> 有才而知进退,福慧双修,这才难得. - ...

  7. BZOJ4398: 福慧双修【二进制分组+最短路】

    4398: 福慧双修 考虑笨蛋,我们可以枚举出边,然后Dij就可以了. 显然在菊花图的情况下要T 我们考虑分组,对于连1的边,一半强制为出边,一半强制为入边,跑DIJ,然后交换,再做一遍. 然后继续分 ...

  8. 【BZOJ3821/UOJ46】玄学(二进制分组,线段树)

    [BZOJ3821/UOJ46]玄学(二进制分组,线段树) 题面 BZOJ UOJ 题解 呜,很好的题目啊QwQ. 离线做法大概可以线段树分治,或者直接点记录左右两次操作时的结果,两个除一下就可以直接 ...

  9. 【BZOJ2069】ZAW(POI2004)-最短路+二进制分组

    测试地址:ZAW 题目大意: 给定一张边是双向的图,一条边走不同的方向可能代价不同,代价都非负,求从点111出发,不经过重复的点或边的最小回路.n≤5000,m≤10000n\le 5000,m\le ...

最新文章

  1. 一键分享(系统所有的软件的分享功能)
  2. Java NIO系列教程(十二) Java NIO与IO
  3. 一个软件项目的总纲性的测试计划叫什么?
  4. 重装系统 计算机意外遇到错误无法运行,win7系统重装笔记本提示"计算机意外的重新启动或遇到错误"的解决方法...
  5. OpenFOAM流固耦合问题-FsiFoam(foam-extend-4.0)运行tutorials的bug修复
  6. 如何区分localhost、127.0.0.1和0.0.0.0等ip地址
  7. js 函数实参列表arguments和形参的那点事儿
  8. 软件测试系统性总结思维导图
  9. zigbee协议栈初使用(四)无线串口透传
  10. 【练习八 结构体(强化)编程题4. 看电影】
  11. android解压rar方法,安卓手机如何解压rar/zip/7z等压缩包 详细图解教程
  12. Authing 背后的计算哲学
  13. linux驱动request_threaded_irq()
  14. 如何激活iPhone XR和XS上的eSIM
  15. 多旅行商问题——公式和求解过程概述
  16. 陈子豪mc虚无世界java_我的世界虚无世界2.5陈子豪整合包
  17. python解析数据包_python – 解析UDP数据包
  18. 第十三届蓝桥杯单片机完整程序
  19. Bootstrap专用图标字体Font Awesome
  20. 串口调试工具xshell的配置

热门文章

  1. 支付宝小程序开发系列二: 获取支付宝用户user_id(.net)
  2. Camtasia2023简单易用的电脑录屏视频剪辑软件
  3. rnnlm源码分析(四)
  4. Java根据两点经纬度计算距离
  5. Java 11,Spring Boot和JavaScript中的i18n
  6. 利用Excel进行相关、回归分析
  7. 软件设计七大设计原则
  8. Solr QueryElevationComponent--实现竞价排名
  9. CVPR2022-SemanticStyleGAN
  10. Arduino融资3200万美元,进军企业市场