bzoj 4398 福慧双修 —— 二进制分组+多起点最短路
题目: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 福慧双修 —— 二进制分组+多起点最短路相关推荐
- bzoj 4398 福慧双修——二进制分组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. ...
- bzoj 2069 [ POI 2004 ] ZAW —— 多起点最短路 + 二进制划分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2069 首先,对于和 1 相连的点,一定是从某个点出发,回到另一个点: 所以需要枚举起点和终点 ...
- BZOJ 2407: 探险/BZOJ 4398: 福慧双修 dijkstra 构造
2407: 探险 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 170 Solved: 95 [Submit][Status][Discuss] ...
- bzoj 4398 福慧双修 题解
卡了一晚上啊 首先我们要跑一边整张图的spfa,记录每个点是从哪条边出去的(pre数组) 这里记录的不是前驱边,而是和原点相连的第一个点编号,因为不能走重复边所以才要记录这个,以免刚刚出去又原路返回 ...
- bzoj 4398: 福慧双修(最短路建模/构造)
简述题意: 给定一个有向图,对于连接同两个点的边算作同一条,问不经过重复边的最小正权环. 保证没有重边(这个是指有向的),没有自环. 算法:最短路+构造 难度:NOIP+ 题解: 有一种暴力的思路,感 ...
- 【技巧 二进制分组】bzoj4398: 福慧双修2407: 探险
二进制分组也可以说是一种比较优美的拆贡献方式吧? Description 菩萨为行,福慧双修,智人得果,不忘其本. --唐朠立<大慈恩寺三藏法师传> 有才而知进退,福慧双修,这才难得. - ...
- BZOJ4398: 福慧双修【二进制分组+最短路】
4398: 福慧双修 考虑笨蛋,我们可以枚举出边,然后Dij就可以了. 显然在菊花图的情况下要T 我们考虑分组,对于连1的边,一半强制为出边,一半强制为入边,跑DIJ,然后交换,再做一遍. 然后继续分 ...
- 【BZOJ3821/UOJ46】玄学(二进制分组,线段树)
[BZOJ3821/UOJ46]玄学(二进制分组,线段树) 题面 BZOJ UOJ 题解 呜,很好的题目啊QwQ. 离线做法大概可以线段树分治,或者直接点记录左右两次操作时的结果,两个除一下就可以直接 ...
- 【BZOJ2069】ZAW(POI2004)-最短路+二进制分组
测试地址:ZAW 题目大意: 给定一张边是双向的图,一条边走不同的方向可能代价不同,代价都非负,求从点111出发,不经过重复的点或边的最小回路.n≤5000,m≤10000n\le 5000,m\le ...
最新文章
- 一键分享(系统所有的软件的分享功能)
- Java NIO系列教程(十二) Java NIO与IO
- 一个软件项目的总纲性的测试计划叫什么?
- 重装系统 计算机意外遇到错误无法运行,win7系统重装笔记本提示"计算机意外的重新启动或遇到错误"的解决方法...
- OpenFOAM流固耦合问题-FsiFoam(foam-extend-4.0)运行tutorials的bug修复
- 如何区分localhost、127.0.0.1和0.0.0.0等ip地址
- js 函数实参列表arguments和形参的那点事儿
- 软件测试系统性总结思维导图
- zigbee协议栈初使用(四)无线串口透传
- 【练习八 结构体(强化)编程题4. 看电影】
- android解压rar方法,安卓手机如何解压rar/zip/7z等压缩包 详细图解教程
- Authing 背后的计算哲学
- linux驱动request_threaded_irq()
- 如何激活iPhone XR和XS上的eSIM
- 多旅行商问题——公式和求解过程概述
- 陈子豪mc虚无世界java_我的世界虚无世界2.5陈子豪整合包
- python解析数据包_python – 解析UDP数据包
- 第十三届蓝桥杯单片机完整程序
- Bootstrap专用图标字体Font Awesome
- 串口调试工具xshell的配置