我的参考题解:https://www.cnblogs.com/ccz181078/p/7907022.html;

不过我感觉题解的压位有问题,(1<<x)还不炸上天。不过这题数据水,好像怎么写都能对,这里放上我认为正确的写法

//正经解法是计算一个F(x)表示经过x的最短路条数,然后找F(A)+F(B)=F(T),用map来做。
//而且F(x)可能很大,还要取模,一个不够的话可能还要取两个。
//而网上的这种随机算法相比之下就显得很简洁了(但由于这题数据很弱好像这部分写错也可以过)
//关于这种做法的正确性,显然所有的最短路都经过的点的f值为0
//那么为什么靠两个f值相同且非0且不能在树形图中互达的点能将图分成两个部分呢,我们可以考虑用一个点将两部分连起来
//这样这个点的f值为0,也就是说它能到所有点,那把它去掉图当然被分成两个部分。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
const int N=5e4+;
int n,m,pp,cp,fa[N],S,T,last[N],pre[N*],other[N*],w[N*],t;
void add(int x,int y,int z){
++t;pre[t]=last[x];last[x]=t;other[t]=y;w[t]=z;
}
struct node{
int id;
i64 dis;
bool operator<(const node&a)const{
return dis>a.dis;
}
}A,B;
priority_queue<node>q;
bool vis[N];
i64 dis[N],ans=;
u64 f[N];
u32 can[N][N/+];
int _get(u32*a,int x){return (a[x>>]>>(x&))&;}
void _set(u32*a,int x){a[x>>]|=<<(x&);}
void _or(u32*a,u32*b){
int p=n/+;
for(int i=;i<=p;i+=){
a[i]|=b[i];a[i+]|=b[i+];
a[i+]|=b[i+];a[i+]|=b[i+];
}
}
void f1(int x){//从T往回找最短路图,我觉得和从S开始找是一样的。
vis[x]=;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
if(dis[v]+w[i]==dis[x]){
if(!vis[v])fa[v]=x,f1(v);
else{
u64 z=rand();
z=z<<^rand();
f[x]^=z;f[fa[v]]^=z;
}
}
}
}
struct hehe{
int id;
u64 v,dis;
bool operator<(const hehe&a)const{
return v!=a.v?v<a.v:dis>a.dis;
}
}tmp[N];
void f2(int x){
_set(can[x],x);
vis[x]=;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
if(dis[v]+w[i]==dis[x]){
if(vis[v])f2(v),f[x]^=f[v];
_or(can[x],can[v]);
}
}
if(f[x])tmp[pp++]=(hehe){x,f[x],dis[x]};
else ++cp;
}
void calc(){
f1(T);f2(T);
sort(tmp,tmp+pp);
for(int i=,j=;i<pp;i=j){
int t=;
for(++j;j<pp&&tmp[i].v==tmp[j].v;++j)t+=_get(can[tmp[i].id],tmp[j].id);
//图一定可以分成两个部分,一部分是经过A的最短路,一部分是经过B的,两部分没有交集。
ans+=i64(j-i-t)*t;//因为f值相同的是按dis值排序的,所以此时的f一定是按A,B分的两个集合中的一个。
}
ans+=cp*i64(n-cp-pp);
printf("%lld\n",ans);
//system("pause");
}
bool dijkstra(){
for(int i=;i<=n;++i)dis[i]=1ll<<;
A.id=S;A.dis=;dis[S]=;q.push(A);
while(!q.empty()){
B=q.top();q.pop();
if(B.dis!=dis[B.id])continue;
if(B.id==T){calc();return ;}
for(int i=last[B.id];i;i=pre[i]){
int v=other[i];
if(dis[v]>dis[B.id]+w[i]){
dis[v]=dis[B.id]+w[i];
A.id=v;A.dis=dis[v];q.push(A);
}
}
}
return ;
}
int main(){
int x,y,z;
cin>>n>>m>>S>>T;
srand(n^m^T^S^);
for(int i=;i<=m;++i){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
if(!dijkstra())printf("%lld\n",n*i64(n-)/);
//system("pause");
return ;
}

bzoj5109(图论好题)的更多相关文章

  1. 11.07图论水题Test

    11.07图论水题Test 题目 描述 做法 \(BSOJ6378\) 在\(i\)位置可以到\(i+a_i\)或\(i+b_i\)求\(1\rightarrow n\)字典序最小路径 判可达性后贪心 ...

  2. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  3. 山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)

    由于我这个破题提交了十四五遍,所以我决定写篇博客来记录一下. 这个题的题目描述是这样的 首先一看这个题我瞬间就想到了一笔画问题(欧拉回路). 对于能够一笔画的图,我们有以下两个定理. 定理1:存在欧拉 ...

  4. D9 图论综合题

    1.白银莲花池 LUOGU 2411 第一种思路:当然我们可以写三个bfs a掉这个题,这写下来一二百行要有了吧: 第二种:我们可以在一个bfs中维护所有的信息,一个方向数组,从起点开始,向八个方向扩 ...

  5. 专题:CF图论杂题

    题目是来自HZW的博客(构造题我是各种不会...) Solved 1 / 1 A CodeForces 500A New Year Transportation Solved 1 / 1 B Code ...

  6. BZOJ 1064: [Noi2008]假面舞会(dfs + 图论好题!)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1064 题意: 思路: 考虑以下几种情况: ①无环并且是树: 无环的话就是树结构了,树结构的话想一下就 ...

  7. 【CZY选讲·一道图论神题】

    题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删掉,但删这个点是需要代价的 ...

  8. 【CZY选讲·一道图论好题】

    题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,不仅有边权还有点权.LYK给出了一个子图的定义,一张图G'={V',E'}被称作G的子图,当且仅当: · ...

  9. 清北学堂模拟赛d2t1 一道图论神题(god)

    题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删掉,但删这个点是需要代价的.假 ...

随机推荐

  1. 模块二 hashlib模块、configparser模块、logging模块

    算法介绍 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常 ...

  2. glide install失败 Update failed for golang.org/x/net: Cannot detect VCS

    失败信息: [WARN]    Unable to checkout golang.org/x/net[ERROR]    Update failed for golang.org/x/net: Ca ...

  3. gdal source code c++ make windows

    下载源码 GDAL源代码下载地址:http://trac.osgeo.org/gdal/wiki/DownloadSource,或者安装svn从源代码服务器下载,svn地址是:http://svn.o ...

  4. 干货分享,40个photoshop技能送给你!

    自从有了“PS(Photoshop)”以后,很多事情变成了可能,你可以上九天揽月,也可以下五洋捉鳖,照片中,你可以出现在任何你想在的地方.而最基本的美化照片的功能,我想是很多同学学习PS的初衷.当你掌 ...

  5. Python之路(第十九篇)hashlib模块

    一.hashlib模块 HASH Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值 ...

  6. Linux 禁止root 用户登录启用sudo

    1.添加sudo用户执行visudo命令,找到: 复制代码 代码如下: root ALL=(ALL) ALL 在下面增加:(注意,qianyunlai 是Linux新增的一个普通用户),没有的话可创建 ...

  7. 关于 construct object opp

    constructor 定义和用法 constructor 属性返回对创建此对象的数组函数的引用. 语法 object.constructor 实例 例子 1 在本例中,我们将展示如何使用 const ...

  8. mybatis不报错,但是查询结果为0

    [转载]https://blog.csdn.net/shenzhenNBA/article/details/46673327 在用MyBatis操作数据库的时候相信很多人都用到,当在判断null, 大 ...

  9. ubuntu下使用fstab挂载硬盘时,属于root,如何把它改为属于一个用户的(如sgjm)

    http://zhidao.baidu.com/link?url=xnakfVD16EtunTSt3wBm153DyqHnXN3FSPO1E_2SpVmM5bmEIwICLA0N6zN85_ioQ3f ...

  10. 绝对强大的三个linux指令: ar, nm, objdump

    前言如果普通编程不需要了解这些东西,如果想精确控制你的对象文件的格式或者你想查看一下文件对象里的内容以便作出某种判断,刚你可以看一下下面的工具:objdump, nm, ar.当然,本文不可能非常详细 ...