Description

探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过!
比赛即将开始,工作人员说明了这次比赛的规则:每个溶洞和其他某些溶洞有暗道相连。两个溶洞之间可能有多条道路,也有可能没有,但没有一条暗道直接从自己连到自己。参赛者需要统一从一个大溶洞出发,并再次回到这个大溶洞。
如果就这么点限制,那么问题就太简单了,可是举办方又提出了一个条件:不能经过同一条暗道两次。这个条件让大家犯难了。这该怎么办呢?
到了大溶洞口后,小T愉悦地发现这个地方他曾经来过,他还记得有哪些暗道,以及通过每条暗道的时间。小T现在向你求助,你能帮他算出至少要多少时间才能回到大溶洞吗?

Input

第一行两个数n,m表示溶洞的数量以及暗道的数量。

接下来m行,每行4个数s、t、w、v,表示一个暗道连接的两个溶洞s、t,这条暗道正着走(s à t)的所需要的时间w,倒着走(t à s)所需要的时间v。由于溶洞的相对位置不同,wv可能不同。

Output

输出一行一个数t,表示最少所需要的时间。

Sample Input

3 3
1 2 2 1
2 3 4 5
3 1 3 2

Sample Output

8

HINT

N<=10000,M<=200000,1<=W,V<=10000

Solution

黄学长的博客讲的挺好的我就不赘述了……毕竟我抄的人家题解

不过黄学长的代码因为存的是前驱点好像有点萎……比如他博客下面那个数据就能叉掉好多人……

稍微改一下改成存前驱边就好了QwQ

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N (1000009)
using namespace std; struct Edge{int to,next,len;}edge[N];
struct Node
{
int num,dis;
bool operator < (const Node a) const {return dis>a.dis;}
};
int n,m,s[N],t[N],w[N],v[N],U,V,W,l,S=,T=;
int head[N],num_edge,dis[N],pre[N],vis[N];
priority_queue<Node>q; void add(int u,int v,int l)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
edge[num_edge].len=l;
head[u]=num_edge;
} int Low(int x){return min(x,((x-)^)+);} void Dijkstra()
{
memset(vis,false,sizeof(vis));
memset(dis,0x7f,sizeof(dis));
dis[]=; q.push((Node){,});
while (!q.empty())
{
Node x=q.top(); q.pop();
if (vis[x.num]) continue;
vis[x.num]=true;
for (int i=head[x.num]; i; i=edge[i].next)
if (dis[x.num]+edge[i].len<dis[edge[i].to])
{
dis[edge[i].to]=dis[x.num]+edge[i].len;
pre[edge[i].to]=(x.num==)?i:pre[x.num];
q.push((Node){edge[i].to,dis[edge[i].to]});
}
}
} int main()
{
scanf("%d%d",&n,&m);
for (int i=; i<=m; ++i)
{
scanf("%d%d%d%d",&s[i],&t[i],&w[i],&v[i]);
add(s[i],t[i],w[i]); add(t[i],s[i],v[i]);
}
Dijkstra();
memset(head,,sizeof(head)); num_edge=;
for (int i=; i<=m; ++i)
for (int j=; j<=; ++j)
{
if (j==) U=s[i],V=t[i],W=w[i];
else U=t[i],V=s[i],W=v[i];
if (V==)
{
if (Low(pre[U])!=Low((i-)*+j)) add(S,T,dis[U]+W);
else add(U,T,W);
}
else if (U==)
{
if (Low(pre[V])!=Low((i-)*+j)) add(,V,W);
}
else
{
if (pre[U]!=pre[V]) add(,V,dis[U]+W);
else add(U,V,W);
}
}
Dijkstra();
printf("%d\n",dis[T]>2e9?-:dis[T]);
}

BZOJ2407/4398:探险/福慧双修(最短路)的更多相关文章

  1. 【BZOJ2407/4398】探险/福慧双修 最短路建模

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

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

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

  3. bzoj 4398 福慧双修 —— 二进制分组+多起点最短路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 按二进制每一位是 0/1 把 1 号点的儿子分成两组,分别作为起点和终点跑多起点最短路 ...

  4. 福慧双修&探险 BZOJ4398&BZOJ2407

    分析: 双倍经验(数据范围不同). 我们考虑,我们必定是从1走一条边到节点i,之后从i到j跑最短路,之后再从j到1走另一条边的情况下,不会重复,并且是答案.那么我们考虑预处理出pre[i]表示从1走到 ...

  5. [BZOJ4398]福慧双修/[BZOJ2407]探险

    题目大意: 给定一个$n(n\leq40000)$个点$m(m\leq100000)$条边的有向图,求从$1$出发回到$1$的不经过重复结点的最短路. 思路: 首先Dijkstra求出从1出发到每个结 ...

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

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

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

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

  8. BZOJ_4398_福慧双修&&BZOJ_2407_探险_分治+dij

    BZOJ_4398_福慧双修&&BZOJ_2407_探险_分治+dij Description 菩萨为行,福慧双修,智人得果,不忘其本. ——唐朠立<大慈恩寺三藏法师传> ...

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

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

随机推荐

  1. 使用YUM安装MySQL 5.5(适用于CentOS6.2/5.8及Fedora 17/16平台)

    目前CentOS/Red Hat (RHEL) 6.2官方自带的mysql版本为5.1,mysql5.5已经出来了. 相比mysql5.1,mysql5.5不仅在多个方面进行了改进: 性能上有了很大提 ...

  2. [H5表单]html5自带表单验证体验优化及提示气泡修改

    慕课网之前录制的视频,js/jquery各种宽高的理解和应用,最近终于上线了.还有一个html5左侧导航没有上线!最近慕课网系列课程让我录制一个html5表单验证的课程.今天就稍微说一下表单验证!另外 ...

  3. [转]微信小程序开发踩坑记录

    本文转自:http://www.cnblogs.com/NKnife/p/6283605.html 1.由于小程序wx.request()方法是异步的,在app.js执行ajax后,各分页加载app. ...

  4. virtualbox xp连不上网

    设置->网络->连接方式:网络地址转换(NAT)->高级->控制芯片:PCnet-FAST III(....) 鸣谢:百度网友:“dei比” 的精彩回答

  5. Swift构造器链

    IDE:Xcode Version7.3.1 指定构造器: 1>名字为init的方法前没有前缀(子类重写时有override除外), 2>一个类中至少有一个指定构造器,其必须初始化类中的所 ...

  6. golang学习之奇葩的time format

    golang格式化时间时,比如如下格式进行格式化输出: fmt.Println(time.Now().Format("2007年03月")) 程序直接输出: 16007年02月 很 ...

  7. springboot1.5.10兼容高版本6.1.1elasticsearch

    1.引入依赖 <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elastic ...

  8. Java并发编程:volatile关键字解析(学习总结-海子)

    博文地址:Java并发编程:volatile关键字解析

  9. css3之背景定位

    属性: background-position: left top || left bottom || right top || right bottom || center center || 像素 ...

  10. sql server query to get the list of column name in a table

    --SQL Server 2005, 2008 or 2012: SELECT * FROM information_schema.tables --SQL Server 2000: SELECT * ...