正题

题目链接:https://darkbzoj.tk/problem/2407


题目大意

\(n\)个点的一张无向图(但是正反权值不同),求一个从\(1\)出发回到\(1\)且不经过重复边的最短路径。

\(1\leq n\leq 10000,1\leq m\leq 2\times 10^5\)


解题思路

考虑一个暴力的做法,枚举一条出边枚举一条入边,然后求出去的点到入点的最短路。

但是这样如果点\(1\)度数很多就会\(T\)。

但是这种问题配最短路是很经典的套路,因为两个不同的数字至少有一个二进制位不同,所以我们可以枚举一个二进制位,然后这个位为\(1\)的当出边,为\(0\)的当入边就好了。

时间复杂度\(O((n+m)\log^2 m)\)


code

#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define mp(x,y) make_pair(x,y)
using namespace std;
const int N=11000;
struct node{
int to,next,w,id,ban;
}a[N*40];
int n,m,tot,ans,ls[N],f[N];bool v[N];
priority_queue<pair<int,int> > q;
inline char Getchar()
{
static char buf[100000],*p1=buf+100000,*pend=buf+100000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,100000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline int read()
{
char c;int d=1;int f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
void addl(int x,int y,int w,int id){
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;a[tot].w=w;
a[tot].id=id;
return;
}
void dij(){
memset(f,0x3f,sizeof(f));
memset(v,0,sizeof(v));
q.push(mp(0,1));f[1]=0;
while(!q.empty()){
int x=q.top().second;q.pop();
if(v[x])continue;v[x]=1;
for(int i=ls[x];i;i=a[i].next){
if(a[i].ban)continue;
int y=a[i].to;
if(f[x]+a[i].w<f[y]){
f[y]=f[x]+a[i].w;
q.push(mp(-f[y],y));
}
}
}
return;
}
int main()
{
tot=1;n=read();m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read(),w=read(),v=read();
addl(x,y,w,i);addl(y,x,v,i);
}
ans=2147483647;
for(int p=0;p<18;p++){
for(int i=2;i<=tot;i++)
if((a[i].id>>p)&1)a[i].ban=(a[i].to==1);
else a[i].ban=(a[i^1].to==1);
dij();
for(int i=2;i<=tot;i++)
if(!a[i].ban&&a[i].to==1)
ans=min(ans,f[a[i^1].to]+a[i].w);
}
printf("%d\n",ans);
return 0;
}

bzoj#2407-探险【最短路,二进制分组】的更多相关文章

  1. HDU - 6166:Senior Pan(顶点集合最短路&二进制分组)

    Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory pro ...

  2. hdu-6166(最短路+二进制分组)

    题意:给你n个点m条边的有向图,然后再给你k个不同的点,问你这k个点的最小距离: 解题思路:这道题最需要注意的就是k个点一定是不同的,那么有一个结论就是任意两个不同的数字中,在他们的二进制地表示中,一 ...

  3. 【刷题】BZOJ 2407 探险

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  4. [bzoj4398] 福慧双修 最短路 二进制分组

    ---题面--- 题解: 考场上看的这道题,,,当时70分算法打挂了,今天才知道这个也是原题.... 首先,对于不跟1相邻的边,肯定不会经过两次,因为经过两次就回来了,除了增加路径长度之外没有任何意义 ...

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

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

  6. 题解 bzoj 4398福慧双修(二进制分组)

    二进制分组,算个小技巧 bzoj 4398福慧双修 给一张图,同一条边不同方向权值不同,一条边只能走一次,求从1号点出发再回到1号点的最短路 一开始没注意一条边只能走一次这个限制,打了个从一号点相邻节 ...

  7. HDU 6166 Senior Pan(二进制分组+最短路)

    题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...

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

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

  9. HDU 6166 Senior Pan(多校第九场 二进制分组最短路)

    题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离 思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点 ...

随机推荐

  1. openssl生成RSA密钥证书

    1.openssl的安装 2.RSA密钥证书的生成 3.openssl的常用命令 1.openssl的安装 openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用.健壮.功能完备的工具套 ...

  2. 【mysql】mysql简介及高手是如何练成的

    1.什么是mysql  MySQL 是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于Oracle 公司. Mysql 是开源的,可以定制的,采用了GPL 协议,你可以修改源码 ...

  3. mfc HackerTools防止程序双开

    来自:https://github.com/TonyChen56/HackerTools 1 HANDLE hMutex = CreateMutexA(NULL, FALSE, "GuiSh ...

  4. 关于Ubuntu18.04 linux系统使用搜狗输入法 出现乱码

    解决: 执行下面的命令即可!无需重启系统 killall fcitx

  5. 再也不用担心了,微软官方系统(win10为例)U盘安装教程

    参考文章地址 使用微软官方工具安装纯净版操作系统. 一.准备工作 检查电脑规格是否支持安装(主要看看系统配置是否满足系统运行的最低要求) 一台联网电脑(不一定非是要装系统的那台): 一个≥8G 空间的 ...

  6. 并发编程之:ThreadLocal

    大家好,我是小黑,一个在互联网苟且偷生的农民工. 从前上一期[并发编程之:synchronized] 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁. 但是,加锁通常情况下会让运行效率 ...

  7. 虚拟dom?diff算法?key?Vue原理的核心三问?打包教你搞定。

    为什么需要虚拟DOM 先介绍浏览器加载一个HTML文件需要做哪些事,帮助我们理解为什么我们需要虚拟DOM.webkit引擎的处理流程,如下图所示: 所有浏览器的引擎工作流程都差不多,如上图大致分5步: ...

  8. GIMP 一键均匀添加多条参考线 一键均匀切分图片

    添加参考线 #!/usr/bin/env python2 # -*- coding: utf-8 -*- from gimpfu import * # orientation: ORIENTATION ...

  9. Mac automator bash 自动操作 右键菜单unrar解压 拷贝文件路径到剪贴板 快速删除(rm -rf) 快捷键设置

    https://tecadmin.net/pass-command-line-arguments-in-shell-script/ https://tecadmin.net/tutorial/bash ...

  10. 集合框架2- ArrayList

    其实 Java 集合框架也叫做容器,主要由两大接口派生而来,一个是 collection,主要存放对象的集合.另外一个是Map, 存储着键值对(两个对象)的映射表. 下面就来说说 List接口,Lis ...