【刷题】BZOJ 2069 [POI2004]ZAW
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的更多相关文章
- 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相 ...
- 2069: [POI2004]ZAW
2069: [POI2004]ZAW 链接 题意: 给定一张带权图(边是双向的,但不同方向长度不同).求从1出发,至少经过除1外的一个点,再回到1的最短路.点和边不能重复经过. n≤5000,m≤10 ...
- bzoj 2096 [POI2004]ZAW——二进制枚举
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2069 可以把直接相连的点分成 从1点出的一部分 和 走向1点的一部分.多起点最短路就和 ...
- 【刷题】BZOJ 2407 探险
Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...
- BZOJ2069: [POI2004]ZAW
2069: [POI2004]ZAW Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 303 Solved: 138[Submit][Status][D ...
- 【刷题】BZOJ 4543 [POI2014]Hotel加强版
Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...
- 【刷题】BZOJ 4316 小C的独立集
Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...
随机推荐
- Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心
传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...
- 【LGR-048 五周年庆贺】洛谷6月月赛
Luogu的五周年庆典比赛,还是比较满意的. 题目清新不毒瘤,数据优质不卡常,解法自然,为出题人点赞. 前三题的难度都很低,T5个人感觉还好.但是最后那个splay+hash是什么神仙东西. 最后好像 ...
- GeForce Experience关闭自动更新
GeForce Experience驱动更新很烦,而且有时更新后就打不开了,找到种方法关闭更新 1.安装并登陆 2.打开 C:\ProgramData\NVIDIA Corporation 3.进入D ...
- NuGet 使用笔记
环境准备 1. 下载nuget : https://www.nuget.org/downloads 2. 设置到环境变量Path, 使生效:在Cmd打入: set path=abc 关闭Cmd (C ...
- MongoDB集群运维笔记
前面的文章介绍了MongoDB副本集和分片集群的做法,下面对MongoDB集群的日常维护操作进行小总结: MongDB副本集故障转移功能得益于它的选举机制.选举机制采用了Bully算法,可以很方便从分 ...
- Coolest Ski Route-不定起点和终点----在有向变的情况下---求最长路
这题最开始给你了N个点,M条边,边是单向边,问不指定起点和终点,最长路是什么??? 脑补一下,不定起点和终点的最短路,用弗洛伊德算法搞一搞,但是...那个垃圾算法的复杂度是N^3的,但是这个算法的M高 ...
- L2-027. 名人堂与代金券
链接:名人堂与代金券 在比赛中这题只得了2分,赛后发现原来strcmp函数并不是只返回-1,0,1三种,而是返回正数负数0 但是在我的电脑上一般就是返回前三种,只是用后面的三种更稳妥点 都怪我基础不扎 ...
- SCRUM 12.20
以下为我们爬虫遇到问题的报告 我们团队的m2阶段原本计划是爬取美团的信息以支持我们的app对比功能,但在这一阶段遇到很多问题,主要表现如下: 美团反爬机制: 由于我们团队人员在事先并不知道美团具有反爬 ...
- 广商博客沖刺第一天(new ver):
項目名稱:廣商博客 沖刺二天傳送門 此次Sprint的目标:全部sprint任務完成 时间:1星期左右 每日立会 Daily Standup Meeting: 1#A3008 晚上8点开始,大概1小时 ...
- Filter(转载)
web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...