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

思路:
  首先Dijkstra求出从1出发到每个结点$i$的单源最短路$dis[i]$及经过的第一个结点$first[i]$。
  考虑重构图,将起点与终点区分开来,新建结点$n+1$表示终点。
  枚举原图中的每一条边$(x,y,w)$,表示从$x$到$y$边权为$w$。
  若$x=1,first[y]\ne y$,在新图中保留这条边;
  若$y=1,first[x]\ne x$,说明存在一条从$1$沿最短路到$x$再到$1$的合法路径,在新图中连边$(1,n+1,w)$;
  若$y=1,first[x]=x$,在新图中保留这条边;
  若$x\ne1,y\ne1,first[x]\ne first[y]$,说明存在一条从$1$沿最短路到$x$再到$y$再沿最短路到$1$的合法路径,连边$(1,y,dis[x]+w)$;
  若$x\ne1,y\ne1,first[x]=first[y]$,在新图中保留这条边。
  最后再求一遍从$1$到$n+1$的最短路即可。

 #include<list>
#include<cstdio>
#include<cctype>
#include<climits>
#include<functional>
#include<ext/pb_ds/priority_queue.hpp>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=;
typedef std::pair<int,int> Edge;
typedef std::list<Edge> List;
typedef std::pair<int,int> Vertex;
typedef __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > Heap;
int n,dis[N],first[N];
List e[N];
inline void add_edge(const int &u,const int &v,const int &w) {
e[u].push_front((Edge){v,w});
}
void dijkstra() {
static Heap q;
static Heap::point_iterator p[N];
for(register int i=;i<=n;i++) {
p[i]=q.push((Vertex){dis[i]=i==?:INT_MAX,i});
}
while(!q.empty()) {
const int &x=q.top().second;
for(register List::iterator i=e[x].begin();i!=e[x].end();i++) {
const int &y=i->first,&w=i->second;
if(dis[x]+w<dis[y]) {
first[y]=x==?y:first[x];
q.modify(p[y],(Vertex){dis[y]=dis[x]+w,y});
}
}
q.pop();
}
}
void rebuild() {
n++;
for(register int x=;x<=n;x++) {
for(register List::iterator i=e[x].begin();i!=e[x].end();e[x].erase(i++)) {
const int &y=i->first,&w=i->second;
if(x==&&first[y]!=y) add_edge(,y,w);
if(y==) first[x]==x?add_edge(x,n,w):add_edge(,n,dis[x]+w);
if(x!=&&y!=) first[x]==first[y]?add_edge(x,y,w):add_edge(,y,dis[x]+w);
}
}
}
int main() {
n=getint();
for(register int m=getint();m;m--) {
const int u=getint(),v=getint();
add_edge(u,v,getint());
add_edge(v,u,getint());
}
dijkstra();
rebuild();
dijkstra();
printf("%d\n",dis[n]==INT_MAX?-:dis[n]);
return ;
}

[BZOJ4398]福慧双修/[BZOJ2407]探险的更多相关文章

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

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

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

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

  3. bzoj4398: 福慧双修

    正边权无向图,一条边两个方向权值不一定相同,求经过点1的最小简单环 简单环包含了点1的一条出边和一条入边,且这两条边不同,因此可以枚举这两条边的编号的二进制表示中哪一位不同,用最短路求此时的最优解,时 ...

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

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

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

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

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

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

  7. BZOJ2407/4398:探险/福慧双修(最短路)

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

  8. 【BZOJ4398】福慧双修(二进制,最短路)

    题意: 此题中S=1 思路:Orz ManGod秒切此题 我觉得出入边权互换不太直观,就改了一下写法 第一次默认与1有关的第一条出边只出不入,第二次默认只入不出 ..]of longint; head ...

  9. bzoj4398:福慧双修

    学习了一下最短路的姿势,这个建图方法好妙啊,虽然不会证明正确性…… #include <bits/stdc++.h> #define N 220000 #define INF 100000 ...

随机推荐

  1. Qt(1)

    Qt Qt开发图形界面软件,可以跨win.linux.mac平台.移动端,使用c++开发 Qt采用所见即所得的UI设计(UI设计和代码是联动的),GUI界面编辑信号和槽,由开发环境自动生成c++代码, ...

  2. Oracle 监听/数据库 启动/关闭

    LSNRCTL命令启动.关闭和查看监听器的状态的方法 从lsnrctl status命令的输出中得到监听器状态,包括如下的信息: 监听器的启动时间 监听器的运行时间 监听器参数文件listener.o ...

  3. 在python中如何比较两个float类型的数据是否相等

    奇怪的现象 前几天跟同事聊起来,在计算机内部float比较是很坑爹的事情.比方说,0.1+0.2得到的结果竟然不是0.3? >>> 0.1+0.2 0.300000000000000 ...

  4. 基于MAC OS 操作系统安装、配置hadoop

    在Mac上安装Hadoop 对我这个之前从未接触过*nix的用户来说,使用命令行来做一系列的事情还是废了一番功夫.特写这个记录,以做备份. 获取Java 我的Mac运行的操作系统是OS X 10.7 ...

  5. javascript replace 替换全部字符

    $("#pageNote").html($("#note3").val().replace(/ /g, "").replace(/<b ...

  6. 【bzoj3670】[Noi2014]动物园 KMP-next数组

    题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法. 某天, ...

  7. POJ 2115 C-Looooops | exgcd

    题目 给出一个循环for(int i=A;i!=B;i+=C) 在mod (1<<k) 下是否可以退出循环 是,输出时间,否输出FORVEER 题解: 题意可以变换成 A+Cx=B (mo ...

  8. Myeclipse中生成subscription code的代码

    //代码如下: package com.qls.AddingMethodsToAnEnum; import java.io.*; public class MyEclipseGen { private ...

  9. GDI+ 双缓存 和 刷新桌面(F5)

    GDI+双缓存 POINT currentPoint; GetCursorPos(&currentPoint); HWND hWnd = ::GetDesktopWindow(); int n ...

  10. Struts2---ActionContext和ServletActionContext小结

    转载自:http://www.cnblogs.com/tanglin_boy/archive/2010/01/18/1650871.html感谢原文作者的总结 1. ActionContext 在St ...