bzoj5109(图论好题)
我的参考题解: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(图论好题)的更多相关文章
- 11.07图论水题Test
11.07图论水题Test 题目 描述 做法 \(BSOJ6378\) 在\(i\)位置可以到\(i+a_i\)或\(i+b_i\)求\(1\rightarrow n\)字典序最小路径 判可达性后贪心 ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- 山东省济南市历城第二中学——洛谷图论入门题--基本题必做 图的遍历—3.骑马修栅栏(fence)
由于我这个破题提交了十四五遍,所以我决定写篇博客来记录一下. 这个题的题目描述是这样的 首先一看这个题我瞬间就想到了一笔画问题(欧拉回路). 对于能够一笔画的图,我们有以下两个定理. 定理1:存在欧拉 ...
- D9 图论综合题
1.白银莲花池 LUOGU 2411 第一种思路:当然我们可以写三个bfs a掉这个题,这写下来一二百行要有了吧: 第二种:我们可以在一个bfs中维护所有的信息,一个方向数组,从起点开始,向八个方向扩 ...
- 专题:CF图论杂题
题目是来自HZW的博客(构造题我是各种不会...) Solved 1 / 1 A CodeForces 500A New Year Transportation Solved 1 / 1 B Code ...
- BZOJ 1064: [Noi2008]假面舞会(dfs + 图论好题!)
http://www.lydsy.com/JudgeOnline/problem.php?id=1064 题意: 思路: 考虑以下几种情况: ①无环并且是树: 无环的话就是树结构了,树结构的话想一下就 ...
- 【CZY选讲·一道图论神题】
题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删掉,但删这个点是需要代价的 ...
- 【CZY选讲·一道图论好题】
题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,不仅有边权还有点权.LYK给出了一个子图的定义,一张图G'={V',E'}被称作G的子图,当且仅当: · ...
- 清北学堂模拟赛d2t1 一道图论神题(god)
题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删掉,但删这个点是需要代价的.假 ...
随机推荐
- linux高级编程——IO
1,文件IO 1)open——打开或创建一个文件 open(char *,flag,mode)在fcntl.h文件中声明. 参数: char * 包含有文件名和路径 flag 打开文件方式 mode ...
- linux操作系统-两台linux服务器SSH免密码登录
A为本地主机(即用于控制其他主机的机器) ; B为远程主机(即被控制的机器Server), ip为192.168.100.247 ; A和B的系统都是Linux 在A上的命令 # ssh-keyg ...
- 百度云的ubuntu16.04.1部署Apache服务器+Django项目
使用Apache和mod_wsgi部署Django 是一种久经考验的将Django投入生产的方法. mod_wsgi是一个Apache模块,可以托管任何Python WSGI应用程序,包括Django ...
- LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree
2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- px转rem
第一步: 第二步:html引入js 第三步:转换单位,100px=0.1rem
- HTML5中的Web Notification桌面通知(右下角提示)
html5桌面通知(Web Notifications)对于需要实现在新消息入线时,有桌面通知效果的情况下非常有用,在此简单介绍一下这个html5的新属性.通过Web Notifications(桌面 ...
- 【机器学习】感知机学习算法(PLA)
感知机问题学习算法引入:信用卡问题 根据已知数据(不同标准的人的信用评级)训练后得出一个能不能给新客户发放信用卡的评定结果 解决该问题的核心思想扔为之前所讲到的梯度下降算法,对于更多条件的类似问题,首 ...
- js中实现 复制到剪切板 功能
一:引包 <script type="text/javascript" src="jquery.js"></script> <sc ...
- centos上安装jdk
今天在centos上安装jdk,总结步骤如下:1.先到oracle下载rpm包:jdk-7u80-linux-x64.rpm (下载地址在百度找找)2.把jdk-7u80-linux-x64.rpm上 ...
- linux_关闭防火墙
centos6版本 永久关闭 chkconfig iptables off 查看状态 chkconfig iptables --list 此时关闭开机重新启动 service iptables sto ...