bzoj4637:期望
思路:最小生成树计数只不过加了一个期望,由于期望具有线性性质,就可以转化为每条边的期望之和,那么一条边的期望如何求呢,在最小生成树记数中,是把相同边权的一起处理,之后把属于连通块内的点缩点,也就是说,一条边只可能在它属于的连通块内对答案产生贡献,之后因为缩点而不会影响答案,因此一条边的期望就等于它在它所属的连通块内包含它的生成树个数除以那个连通块的生成树个数,而包含这条边的生成树个数就是该连通块内所有的生成树个数减去不包含这条边的生成树个数,然后用matrix-tree定理统计答案即可,因为这题要枚举边,所以最好写两个并查集,反正我之前的dfs写法没法写。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define maxm 200005
#define maxn 10005
const long double eps=1e-9; int n,m,cnt,top;
int pos[maxn],stack[maxn];
bool instack[maxn];
long long tot;
long double ans,K[1000][1000],T[1000][1000]; vector<int> v[maxn]; struct edge{
int from,to,dis,val;
bool operator <(const edge &a)const{return dis<a.dis;}
}e[maxm]; inline int read(){
int x=0;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar());
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x;
} struct union_find_set{
int fa[maxn];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
}u1,u2; long long gauss(){
int t,n=cnt-1,f=1;long double ans=1;
for (int i=1;i<n;i++){
for (t=i;t<=n;t++) if (fabs(K[t][i])>eps) break;if (t>n) return 0;
if (t!=i){for (int j=1;j<=n;j++) swap(K[i][j],K[t][j]);f=-f;}
for (int j=i+1;j<=n;j++)
if (fabs(K[j][i])>eps){
long double t=K[j][i]/K[i][i];
for (int k=i;k<=n;k++) K[j][k]-=K[i][k]*t;
}
}
for (int i=1;i<=n;i++) ans=ans*K[i][i];
return round(ans*f);
} void add(int x,int y,int val){
K[x][y]-=val,K[y][x]-=val;
K[x][x]+=val,K[y][y]+=val;
} int main(){
n=read(),m=read();
for (int i=1;i<=m;i++) e[i].from=read(),e[i].to=read(),e[i].dis=read(),e[i].val=read();
for (int i=1;i<=n;i++) u1.fa[i]=u2.fa[i]=i; sort(e+1,e+m+1);
for (int i=1,l=1;i<=m+1;i++){
int x=u1.find(e[i].from),y=u1.find(e[i].to);
if (x!=y){int u=u2.find(x),v=u2.find(y);if (u!=v) u2.fa[u]=v;}
if (e[i].dis!=e[i+1].dis){
for (int j=l;j<=i;j++){
int x=u1.find(e[j].from),y=u1.find(e[j].to);
if (x==y) continue; int u=u2.find(x);
if (!instack[u]) stack[++top]=u,instack[u]=1;
}
while (top){
instack[stack[top]]=0,cnt=0;
for (int j=l;j<=i;j++){
int x=u1.find(e[j].from),y=u1.find(e[j].to);
if (x==y) continue; int u=u2.find(x);
if (u==stack[top]){
if (!pos[x]) pos[x]=++cnt;
if (!pos[y]) pos[y]=++cnt;
add(pos[x],pos[y],1);
}
}
for (int a=1;a<=cnt;a++)
for (int b=1;b<=cnt;b++)
T[a][b]=K[a][b];
tot=gauss();
for (int a=1;a<=cnt;a++)
for (int b=1;b<=cnt;b++)
K[a][b]=T[a][b];
for (int j=l;j<=i;j++){
int x=u1.find(e[j].from),y=u1.find(e[j].to);
if (x==y) continue; int u=u2.find(x);
if (u==stack[top]){
for (int a=1;a<=cnt;a++)
for (int b=1;b<=cnt;b++)
T[a][b]=K[a][b];
add(pos[x],pos[y],-1);
long long tmp=gauss();
for (int a=1;a<=cnt;a++)
for (int b=1;b<=cnt;b++)
K[a][b]=T[a][b];
ans+=1.0*(tot-tmp)/tot*e[j].val;
}
}
for (int j=l;j<=i;j++){
int x=u1.find(e[j].from),y=u1.find(e[j].to);
if (x==y) continue;pos[x]=pos[y]=0;
}
for (int j=1;j<=cnt;j++)
for (int k=1;k<=cnt;k++)
K[j][k]=0;
top--;
}
for (int j=l;j<=i;j++){
int x=u1.find(e[j].from),y=u1.find(e[j].to);
if (x==y) continue;u1.fa[x]=y;
}
l=i+1;
}
}
printf("%.5lf",(double)ans);
return 0;
}
bzoj4637:期望的更多相关文章
- bzoj4637: 期望
Description 在米国有一所大学,名叫万国歌剧与信息大学(UniversalOperaandInformaticasUniversity).简称UOI大学.UO I大学的建筑与道路分布很有趣, ...
- 【BZOJ4637】期望 Kruskal+矩阵树定理
[BZOJ4637]期望 Description 在米国有一所大学,名叫万国歌剧与信息大学(UniversalOperaandInformaticasUniversity).简称UOI大学.UOI大学 ...
- 【BZOJ-3143】游走 高斯消元 + 概率期望
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2264 Solved: 987[Submit][Status] ...
- bzoj1415[NOI2005]聪聪和可可-期望的线性性
这道题之前我写过一个巨逗比的写法(传送门:http://www.cnblogs.com/liu-runda/p/6220381.html) 当时的原因是这道题可以抽象出和"绿豆蛙的归宿&qu ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
- 【BZOJ3036】绿豆蛙的归宿 概率与期望
最水的概率期望,推荐算法合集之<浅析竞赛中一类数学期望问题的解决方法> #include <iostream> #include <cstdio> using na ...
- UVA&&POJ离散概率与数学期望入门练习[4]
POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...
- 【BZOJ-1426】收集邮票 概率与期望DP
1426: 收集邮票 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 261 Solved: 209[Submit][Status][Discuss] ...
- 【BZOJ-1419】Red is good 概率期望DP
1419: Red is good Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 660 Solved: 257[Submit][Status][Di ...
随机推荐
- Asp.Net事务和异常处理:
Asp.Net事务和异常处理: 一.什么是事务处理? 事务处理是一组组和成逻辑工作单元的数据库操作,虽然系统中可能会出错,但事务将控制和维护每个数据库的一致性和完整性. 如果在事务过程中没有遇到错误, ...
- Java文件操作源码大全
Java文件操作源码大全 1.创建文件夹 52.创建文件 53.删除文件 54.删除文件夹 65.删除一个文件下夹所有的文件夹 76.清空文件夹 87.读取文件 88.写入文件 99.写入随机文件 9 ...
- iOS开发——Swift篇&Swift关键字详细介绍
Swift关键字详细介绍 每一种语言都有相应的关键词,每个关键词都有他独特的作用,来看看swfit中的关键词: 关键词: 用来声明的: “ class, deinit, enum, extension ...
- JavaScript(20)jQuery HTML 加入和删除元素
jQuery - 加入元素 通过 jQuery,能够非常easy地加入新元素/内容. 加入新的 HTML 内容的四个 jQuery 方法: append() - 在被选元素的结尾插入内容 prepen ...
- [node.js]RPC(远程过程调用)的实现原理
刚接触到RPC(远程过程调用),就是可以在本地调用远程机子上的程序的方法,看到一个简单的nodejs实现,用来学习RPC的原理很不错:nodejs light_rpc 使用示例: //服务端 ...
- android122 zhihuibeijing 主页面搭建
右边主页面布局设计: 文字颜色选择器和是否点击的图片选择器 路径和写法: <?xml version="1.0" encoding="utf-8"?&g ...
- debian 系统备份
tar -zcvpf /home/full-backup.tar.gz / --exclude=/mnt/* --exclude=/proc/* --exclude=/sys/* 这个命令是把根目录下 ...
- QT: QByteArray储存二进制数据(包括结构体,自定义QT对象)
因为利用QByteArray可以很方便的利用其API对内存数据进行访问和修改, 构建数据库blob字段时必不可少; 那如何向blob内写入自定义的结构体和类 1. 利用memcpy拷贝内存数据 / ...
- Regular Expressions --正则表达式官方教程
http://docs.oracle.com/javase/tutorial/essential/regex/index.html This lesson explains how to use th ...
- 如何查找局域网的外网ip
方法一:一个简单的方法 用你电脑打开www.ip138.com 就可以看到自己的公网IP地址 方法二:如果一定要从路由器里面看 那就打开路由的配置页面 一般在系统状态里面 会有个WAN口IP 那就是你 ...