【BZOJ4637】期望 Kruskal+矩阵树定理
【BZOJ4637】期望
Description
Input
Output
一行一个整数,即满足总道路长度最小的情况下,设计方案的美学值期望。要求保留5位小数
Sample Input
1 2 3 4
Sample Output
题解:傻题细节多啊~
我们先进行Kruskal求距离值的最小生成树,如果有多条边权值相同,则我们将它们放到一起处理。我们再把加入后会被分到同一个连通块中的边放到一起,并把连通块离散化缩成点。因为期望是可加的,所以我们可以枚举其中的每条边,这条边出现的概率就是总的缩点后的图的生成树数目 分之 保证这条边在内时剩余图的生成树数目。拿矩阵树定理算一下就好了,用long double即可过。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
const int maxn=10010;
const int maxm=200010;
typedef long double db;
const db eps=1e-6;
struct edge
{
int a,b,c,d;
}p[maxm];
int n,m,tot,tp,now;
int f[maxn],bel[maxn],g[65],vis[maxn],st[40],pa[40],pb[40],qa[40],qb[40],ref[65];
int qs[65][40],qt[65],ps[65][40],pt[65];
db v[40][40],ans;
bool cmp(const edge &a,const edge &b)
{
return a.c<b.c;
}
inline int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
inline int gind(int x)
{
return (g[x]==x)?x:(g[x]=gind(g[x]));
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline double gauss(int N)
{
db ret=1;
int i,j,k;
for(i=1;i<N;i++)
{
for(j=k=i;j<N;j++) if(fabs(v[j][i])>fabs(v[k][i])) k=j;
if(k!=i) for(ret=-ret,j=1;j<N;j++) swap(v[i][j],v[k][j]);
if(fabs(v[i][i])<1e-6) return 0;
for(j=1;j<N;j++) if(j!=i&&fabs(v[j][i])>1e-6)
{
db tmp=v[j][i]/v[i][i];
for(k=1;k<N;k++) v[j][k]-=v[i][k]*tmp;
}
ret=ret*v[i][i];
}
return ret;
}
inline void calc(int x)
{
int i,j,a,b;
for(i=1;i<=pt[x];i++) ref[ps[x][i]]=i;
for(i=1;i<=qt[x];i++) qa[i]=ref[pa[qs[x][i]]],qb[i]=ref[pb[qs[x][i]]];
memset(v,0,sizeof(v));
for(i=1;i<=qt[x];i++) a=qa[i],b=qb[i],v[a][a]++,v[b][b]++,v[a][b]--,v[b][a]--;
double tmp=gauss(pt[x]);
for(i=1;i<=qt[x];i++)
{
memset(v,0,sizeof(v));
if(qa[i]>qb[i]) swap(qa[i],qb[i]);
for(j=1;j<=qt[x];j++) if(i!=j)
{
a=qa[j],b=qb[j];
if(a==qb[i]) a=qa[i];
if(a>qb[i]) a--;
if(b==qb[i]) b=qa[i];
if(b>qb[i]) b--;
v[a][a]++,v[b][b]++,v[a][b]--,v[b][a]--;
}
ans+=gauss(pt[x]-1)*p[st[qs[x][i]]].d/tmp;
}
qt[x]=pt[x]=0;
}
inline void solve()
{
int i,a,b;
now++,tot=0;
for(i=1;i<=tp;i++)
{
if(vis[find(p[st[i]].a)]!=now) vis[f[p[st[i]].a]]=now,bel[f[p[st[i]].a]]=++tot;
if(vis[find(p[st[i]].b)]!=now) vis[f[p[st[i]].b]]=now,bel[f[p[st[i]].b]]=++tot;
pa[i]=bel[f[p[st[i]].a]],pb[i]=bel[f[p[st[i]].b]];
}
for(i=1;i<=tot;i++) g[i]=i;
for(i=1;i<=tp;i++)
{
a=gind(pa[i]),b=gind(pb[i]);
if(a!=b) g[a]=b;
}
for(i=1;i<=tp;i++) a=gind(pa[i]),qs[a][++qt[a]]=i;
for(i=1;i<=tot;i++) a=gind(i),ps[a][++pt[a]]=i;
for(i=1;i<=tot;i++) if(gind(i)==i) calc(i);
for(i=1;i<=tp;i++)
{
a=find(p[st[i]].a),b=find(p[st[i]].b);
if(a!=b) f[a]=b;
}
tp=0;
}
int main()
{
//freopen("bz4637.in","r",stdin);
n=rd(),m=rd();
int i,a,b,pre=0;
for(i=1;i<=m;i++) p[i].a=rd(),p[i].b=rd(),p[i].c=rd(),p[i].d=rd();
sort(p+1,p+m+1,cmp);
for(i=1;i<=n;i++) f[i]=i;
for(i=1;i<=m;i++)
{
if(p[i].c>pre&&pre) solve();
a=find(p[i].a),b=find(p[i].b);
if(a==b) continue;
st[++tp]=i,pre=p[i].c;
}
solve();
printf("%.5Lf",ans);
return 0;
}//3 3 1 2 1 4 1 3 1 6 2 3 1 8
【BZOJ4637】期望 Kruskal+矩阵树定理的更多相关文章
- bzoj1016 [JSOI2008]最小生成树计数——Kruskal+矩阵树定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 从 Kruskal 算法的过程来考虑产生多种方案的原因,就是边权相同的边有一样的功能, ...
- 矩阵树定理&BEST定理学习笔记
终于学到这个了,本来准备省选前学来着的? 前置知识:矩阵行列式 矩阵树定理 矩阵树定理说的大概就是这样一件事:对于一张无向图 \(G\),我们记 \(D\) 为其度数矩阵,满足 \(D_{i,i}=\ ...
- [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)
In some countries building highways takes a lot of time... Maybe that's because there are many possi ...
- BZOJ 4766: 文艺计算姬 [矩阵树定理 快速乘]
传送门 题意: 给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图$K_{n,m}$ 求生成树个数 1 <= n,m,p <= 10^18 显然不能暴力上矩阵树定理 看 ...
- bzoj 4596 [Shoi2016]黑暗前的幻想乡 矩阵树定理+容斥
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 559 Solved: 325[Submit][Sta ...
- 【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)
[LOJ#6072]苹果树(矩阵树定理,折半搜索,容斥) 题面 LOJ 题解 emmmm,这题似乎猫讲过一次... 显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满 ...
- 2019.01.02 bzoj2467: [中山市选2010]生成树(矩阵树定理)
传送门 矩阵树定理模板题. 题意简述:自己看题面吧太简单懒得写了 直接构建出这4n4n4n个点然后按照题面连边之后跑矩阵树即可. 代码: #include<bits/stdc++.h> # ...
- [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...
- 【bzoj4596】[Shoi2016]黑暗前的幻想乡 容斥原理+矩阵树定理
题目描述 给出 $n$ 个点和 $n-1$ 种颜色,每种颜色有若干条边.求这张图多少棵每种颜色的边都出现过的生成树,答案对 $10^9+7$ 取模. 输入 第一行包含一个正整数 N(N<=17) ...
随机推荐
- 谷歌、亚马逊相继宣布屏蔽 Flash 广告,又一个时代行将结束?【转载+整理】
原文地址 其实,如果你看一下乔布斯的传记,早在十几年以前,乔布斯就说过类似的话,他狠透了 Flash~ 据 InfoWorld 报道,谷歌已经正式宣布,在默认情况下,Chrome将不再自动播放Web页 ...
- mock以及特殊场景下对mock数据的处理
一.为什么要mock 工作中遇到以下问题,我们可以使用mock解决: 无法控制第三方系统某接口的返回,返回的数据不满足要求 某依赖系统还未开发完成,就需要对被测系统进行测试 有些系统不支持重复请求,或 ...
- Linux cut命令用法
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的.一般来说,选取信息通常是针对“行”来进行分析的,并不是整篇信息分析的. (1)其语法格式为: cut [-bn] [file] 或 cu ...
- 外网IP监测上报程序(使用Poco库的SMTPClientSession发送邮件)
目录 IPReport 项目介绍 编译说明 安装使用说明 获取外网IP方式 邮件发送关键代码 IPReport 代码地址https://gitee.com/solym/IPReport 项目介绍 外网 ...
- dos 批量重命名 bat
@echo off setlocal enabledelayedexpansion echo %var% set /a i = i + var for %%x in (*) do ( if not & ...
- CentOS---网络配置详解 (转)
一.配置文件详解在RHEL或者CentOS等Redhat系的Linux系统里,跟网络有关的主要设置文件如下: /etc/host.conf 配置域名服务客户端的控制文件/etc/hos ...
- xcode 报错 malloc: *** error for object 0x6c3c5a4: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug------d
大家有时候会遇到这个错误 malloc: *** error for object 0x******: incorrect checksum for freed object - object was ...
- IDEA环境设置
设置SDK:https://blog.csdn.net/y999666/article/details/51893348 打开模板使用说明,找到Maven本地安装目录, 备份E:\Program Fi ...
- SQLServer 数据库变成单个用户后无法访问问题的解决方法
USE master; GO DECLARE @SQL VARCHAR(MAX); SET @SQL='' SELECT @SQL=@SQL+'; KILL '+RTRIM(SPID) FROM ma ...
- 完美的代码生成器SNF.CodeGenerator-快速开发者的利器--SNF快速开发平台3.1
第1章 SNF.CodeGenerator代码生成器简介 本项目是完全基于Spring.Net.Framework 平台进行研发.与Spring.Net.Framework平台无缝衔接.并支持模型层. ...