Description

在Byte山的山脚下有一个洞穴入口. 这个洞穴由复杂的洞室经过隧道连接构成. 洞穴的入口是一条笔直通向“前面洞口”的道路. 隧道互相都不交叉(他们只在洞室相遇). 两个洞室要么就通过隧道连接起来,要么就经过若干隧道间接的相连. 现在决定组织办一个'King's of Byteotia Cup' 比赛. 参赛者的目标就是任意选择一条路径进入洞穴并尽快出来即可. 一条路径必须经过除了“前面洞口”之外还至少要经过其他一个洞室.一条路径中一个洞不能重复经过(除了“前面洞室”以外),类似的一条隧道也不能重复经过. 一个著名的洞穴探险家 Byteala 正准备参加这个比赛. Byteala 已经训练了数月而且他已获得了洞穴系统的一套详细资料. 对于每条隧道他都详细计算了从两个方向经过所需要的时间. 经过一个洞室的时间很短可以忽略不记. 现在Byteala 向计算一条符合条件的最优路径.

Input

第一行有两个数n 和 m (3 <= n <= 5000, 3 <= m <= 10000) 分别表示洞室的数目以及连接他们的隧道的数目. 洞室从1 到 n编号. “前面洞室”的编号为1. 接下来m 行描述了所有的隧道. 每行四个整数a,b,c,d 表示从洞室a到洞室b需要c分钟的时间,而从洞室b到洞室a需要d分钟的时间, 1 <= a,b <= n, a <> b, 1 <= c,d <= 10000. 你可以假设符合要求的路径肯定存在.

Output

输出一行,最少需要多少时间完成比赛.

Sample Input

3 3

1 2 4 3

2 3 4 2

1 3 1 1

Sample Output

6

Solution

这是一个假二进制分组

对一号点相连的点按照二进制来分组

枚举二进制,一种只能由1走向它,另一种只能由它走向1

然后每次都跑一边Dijkstra就好了

因为任意两个点一定在一个数的二进制中在不同的分组,所以方案经过的两个点一定会被枚举到

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define ft first
#define sd second
#define pb(a) push_back(a)
#define mp(a,b) std::make_pair(a,b)
#define ITR(a,b) for(auto a:b)
#define REP(a,b,c) for(register int a=(b),a##end=(c);a<=a##end;++a)
#define DEP(a,b,c) for(register int a=(b),a##end=(c);a>=a##end;--a)
const int MAXN=10000+10,MAXM=200000+10,inf=0x3f3f3f3f;
int n,m,e,beg[MAXN],nex[MAXM<<1],to[MAXM<<1],was[MAXM<<1],d[MAXN],dir[MAXN],ans=inf;
std::priority_queue< std::pair<int,int>,std::vector< std::pair<int,int> >,std::greater< std::pair<int,int> > > q;
namespace IO{
const int Buffsize=1<<15,Output=1<<24;
static char Ch[Buffsize],*S=Ch,*T=Ch;
inline char getc()
{
return((S==T)&&(T=(S=Ch)+fread(Ch,1,Buffsize,stdin),S==T)?0:*S++);
}
static char Out[Output],*nowps=Out;
inline void flush(){fwrite(Out,1,nowps-Out,stdout);nowps=Out;}
template<typename T>inline void read(T&x)
{
x=0;static char ch;T f=1;
for(ch=getc();!isdigit(ch);ch=getc())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getc())x=x*10+(ch-'0');
x*=f;
}
template<typename T>inline void write(T x,char ch='\n')
{
if(!x)*nowps++='0';
if(x<0)*nowps++='-',x=-x;
static int sta[111],tp;
for(tp=0;x;x/=10)sta[++tp]=x%10;
for(;tp;*nowps++=sta[tp--]^48);
*nowps++=ch;
}
}
using namespace IO;
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y,int z)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
was[e]=z;
}
inline void Dijstra(int s)
{
memset(d,inf,sizeof(d));
d[s]=0;
q.push(mp(d[s],s));
while(!q.empty())
{
std::pair<int,int> pr=q.top();
q.pop();
if(pr.ft!=d[pr.sd])continue;
int x=pr.sd;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==1)
{
if(dir[x])continue;
if(d[n+1]>d[x]+was[i])d[n+1]=d[x]+was[i];
}
else
{
if(x==1&&!dir[to[i]])continue;
if(d[to[i]]>d[x]+was[i])d[to[i]]=d[x]+was[i],q.push(mp(d[to[i]],to[i]));
}
}
}
inline void solve(int ps)
{
for(register int i=beg[1];i;i=nex[i])dir[to[i]]=(to[i]>>ps)&1;
Dijstra(1);
chkmin(ans,d[n+1]);
for(register int i=beg[1];i;i=nex[i])dir[to[i]]^=1;
Dijstra(1);
chkmin(ans,d[n+1]);
}
int main()
{
read(n);read(m);
REP(i,1,m)
{
int u,v,w1,w2;read(u);read(v);read(w1);read(w2);
insert(u,v,w1);insert(v,u,w2);
}
REP(i,0,13)solve(i);
write(ans,'\n');flush();
return 0;
}

【刷题】BZOJ 2069 [POI2004]ZAW的更多相关文章

  1. BZOJ 2069: [POI2004]ZAW(Dijkstra + 二进制拆分)

    题意 给定一个有 \(N\) 个点 \(M\) 条边的无向图, 每条无向边 最多只能经过一次 . 对于边 \((u, v)\) , 从 \(u\) 到 \(v\) 的代价为 \(a\) , 从 \(v ...

  2. BZOJ.2069.[POI2004]ZAW(最短路Dijkstra 按位划分)

    题目链接 \(Description\) 给定一张带权图(边是双向的,但不同方向长度不同).求从1出发,至少经过除1外的一个点,再回到1的最短路.点和边不能重复经过. \(n\leq5000,m\le ...

  3. BZOJ 2069 POI2004 ZAW 堆优化Dijkstra

    题目大意:给定一张无向图.每条边从两个方向走各有一个权值,求从点1往出走至少一步之后回到点1且不经过一条边多次的最短路 显然我们须要从点1出发走到某个和点1相邻的点上,然后沿最短路走到还有一个和点1相 ...

  4. 2069: [POI2004]ZAW

    2069: [POI2004]ZAW 链接 题意: 给定一张带权图(边是双向的,但不同方向长度不同).求从1出发,至少经过除1外的一个点,再回到1的最短路.点和边不能重复经过. n≤5000,m≤10 ...

  5. bzoj 2096 [POI2004]ZAW——二进制枚举

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2069 可以把直接相连的点分成  从1点出的一部分  和  走向1点的一部分.多起点最短路就和 ...

  6. 【刷题】BZOJ 2407 探险

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

  7. BZOJ2069: [POI2004]ZAW

    2069: [POI2004]ZAW Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 303  Solved: 138[Submit][Status][D ...

  8. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  9. 【刷题】BZOJ 4316 小C的独立集

    Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...

随机推荐

  1. 4.5《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)—第四章小结

    本章相关重要命令总结在Table 6. 命令 描述 示例 mkdir <name> 创建某目录 $ mkdir foo pwd 显示当前所在目录 $ pwd cd <dir> ...

  2. WPF解决界面全屏化但不遮挡任务栏的问题

    原文:WPF解决界面全屏化但不遮挡任务栏的问题 学习C#有一段时间了,现在跟着做项目,碰到有个客户端界面总是全屏,对于客户来说没有任务栏很不习惯,所以做了些略微的修改   </pre>&l ...

  3. .NET Core在类库中读取配置文件appsettings.json

    在.NET Framework框架时代我们的应用配置内容一般都是写在Web.config或者App.config文件中,读取这两个配置文件只需要引用System.Configuration程序集,分别 ...

  4. UWP简单示例(二):快速开始你的3D编程

    准备 IDE:Visual Studio 开源库:GitHub.SharpDx 入门示例:SharpDX_D3D12HelloWorld 为什么选择 SharpDx? SharpDx 库与 UWP 兼 ...

  5. item 12: 把重写函数声明为“override”的

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 C++中的面向对象编程总是围绕着类,继承,以及虚函数.这个世界中, ...

  6. Linux服务器更换主板后,网卡识别失败的处理方法

    1)现象说明公司IDC机房里的一台线上服务器硬件报警,最后排查发现服务器主板坏了,随即联系厂商进行更换主板,最后更换后,登录服务器,发现网卡绑定及ip信息都在,但是ip却ping不通了,进一步排查,重 ...

  7. 如何在css中设置按钮button中包含图片文字对齐方式

    <el-button class="class-management style="line-heught">班级管理

  8. b总结

    Beta 答辩总结 评审表 组名 格式 内容 ppt 演讲 答辩 总计 天机组 15 15 13 15 14 72 PMS 16 16 15 16 16 79 日不落战队 16 17 17 17 17 ...

  9. K 班前7次作业成绩汇总

    K 班前7次作业成绩汇总 得分榜 千帆竞发 详细 短学号 名 1 2 3 4 5 6 7 TOTAL 505 基智 4.55 1 -2 0 0 -10 4.37 -2.08 414 圳源 5.43 2 ...

  10. realm vs. domain

    从wiki的角度:https://wikidiff.com/domain/realm domain是物理的,realm是抽象的,都是领域. domain是一个人或组织拥有或控制的地理区域,而realm ...