正边权无向图,一条边两个方向权值不一定相同,求经过点1的最小简单环

简单环包含了点1的一条出边和一条入边,且这两条边不同,因此可以枚举这两条边的编号的二进制表示中哪一位不同,用最短路求此时的最优解,时间复杂度$O(mlog^2m)$

#include<bits/stdc++.h>
using std::swap;
using std::vector;
using std::priority_queue;
const int N=,inf=;
int _(){
int x=,c=getchar();
while(c<)c=getchar();
while(c>)x=x*+c-,c=getchar();
return x;
}
int n,m;
struct edge{
int to,v;
bool operator<(edge e)const{return v>e.v;}
};
int l[N],ans=inf;
priority_queue<edge>q;
vector<edge>es[N],eS,eT;
bool ed[];
void mins(int&a,int b){if(a>b)a=b;}
void cal(){
q=priority_queue<edge>();
for(int i=;i<=n;++i)l[i]=inf;
for(int i=;i<eS.size();++i)if(ed[i]){
edge w=eS[i];
if(l[w.to]>w.v)q.push((edge){w.to,l[w.to]=w.v});
}
while(q.size()){
edge w=q.top();q.pop();
if(w.v>=ans)break;
if(w.v!=l[w.to])continue;
for(int i=;i<es[w.to].size();++i){
edge u=es[w.to][i];
if(l[u.to]>w.v+u.v)q.push((edge){u.to,l[u.to]=w.v+u.v});
}
}
for(int i=;i<eT.size();++i)if(!ed[i]){
edge w=eT[i];
mins(ans,l[w.to]+w.v);
}
}
int main(){
n=_(),m=_();
for(int i=,a,b,v1,v2;i<m;++i){
a=_(),b=_(),v1=_(),v2=_();
if(a==b)continue;
if(a==||b==){
if(b==)swap(a,b),swap(v1,v2);
eS.push_back((edge){b,v1});
eT.push_back((edge){b,v2});
}else{
es[a].push_back((edge){b,v1});
es[b].push_back((edge){a,v2});
}
}
for(int t=;t<eS.size();t<<=){
for(int i=;i<eS.size();++i)ed[i]=i&t;
cal();
for(int i=;i<eS.size();++i)ed[i]^=;
cal();
}
printf("%d\n",ans);
return ;
}

bzoj4398: 福慧双修的更多相关文章

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

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

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

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

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

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

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

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

  5. bzoj4398:福慧双修

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

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

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

  7. 【BZOJ4398】福慧双修 题解(建图优化)

    题目链接 题目大意:给定一张$n$个点$m$条边的无向图,每条边两个方向的权值不一定相同.问从$1$出发不重复走一条边回到$1$的最短路径. ------------------- 暴力不太会.大概是 ...

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

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

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

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

随机推荐

  1. Python 模块管理1

    Python 模块管理   导入新的模块 创建一个 calculate.py 文件 print('ok') def add(x,y): return x + y def sub(x,y): retur ...

  2. java super的用法

    通过用static来定义方法或成员,从某种程度上可以说它类似于C语言中的全局函数和全局变量. this&super这两个关键字的意义和用法. 在Java中,this通常指当前对象,super则 ...

  3. 比较器(TreeSet和优先队列,可以对里面的元素按照自己的意愿进行排序)

    class MyComparator implements Comparator<Integer>{ public int compare(Integer o1, Integer o2) ...

  4. 剑指offer-反向遍历链表-栈和递归2种方法(一次性跑通)

  5. "ERR unknown command 'cluster'"

    golang 连接redis 集群提示  "ERR unknown command 'cluster'" redisdb = redis.NewClusterClient(& ...

  6. MySQL--时间戳属性1

    ============================================================================== DATETIME类型和TIMESTAMP类 ...

  7. ipfs docker 运行试用

    ipfs 是一个分布式,p2p 的文件系统,参考了git.bt.sfs 以及web 的设计 环境准备 docker-compose 文件 version: "3" services ...

  8. The dis/advantage of forward declaration

    In our projects, in C++ head file, if reference to some classes (reference or pointer), instead of i ...

  9. 01c++学习

    #include"iostream" using namespace std; void main01() { //printf("hello_world\n" ...

  10. ML(附录3)——过拟合与欠拟合

    过拟合与欠拟合 我们希望机器学习得到好的模型,该模型能够从训练样本中找到一个能够适应潜在样本的普遍规律.然而,如果机器学习学的“太好”了,以至把样本的自身特点当作潜在样本的一般特性,这就使得模型的泛化 ...