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 ...
随机推荐
- 理解js中的原型链,prototype与__proto__的关系
说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type="text/javascript"> 2 var Pers ...
- .NET MVC4 ApiController拦截器的使用
目前在公司新开发了一个项目,第一次正式使用.NET MVC4来搭建,用拦截器来处理权限验证. 自定义拦截器需继承ActionFilterAttribute类,重写OnActionExecuting和O ...
- 剑指OFFER之从1到n中出现1的次数(九度OJ1373)
题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他.问题是:求出1~13的整数中1出现的次数,并算出100~130 ...
- SQLite 使用教程2 语法
http://www.runoob.com/sqlite/sqlite-syntax.html SQLite 语法 SQLite 是遵循一套独特的称为语法的规则和准则.本教程列出了所有基本的 SQLi ...
- EntityFramework 连接数据库出错
本文转载:http://www.cnblogs.com/shuang121/archive/2012/03/19/2406121.html 总结:选择“是”时,连接字符串的密码会暴露出来,“否”的时候 ...
- MySQL5日期类型DATETIME和TIMESTAMP相关问题详解
MySQL5日期类型DATETIME和TIMESTAMP相关问题详解 MySQL5的日期类型有三种:DATETIME.DATE和TIMESTAMP,除了DATE用来表示一个不带时分秒的是日期,另外两个 ...
- Chord算法(原理)
Chrod算法是P2P中的四大算法之中的一个,是有MIT(麻省理工学院)于2001年提出,其它三大算法各自是: CAN Pastry Tapestry Chord的目的是提供一种能在P2P网络高速定位 ...
- Xcode repository host is unreachable
遇到这个错误,首先不要急.按照如下方法即可(如果你的svn地址没有问题的话): url要使用域名,所以映射下 1. 修改host:在应用程序里面打开终端(terminal),输入 sudo vi /e ...
- Upgrading to MySQL 5.7---focusing on temporal types
https://www.percona.com/blog/2016/04/27/upgrading-to-mysql-5-7-focusing-on-temporal-types/ http://ww ...
- Android 带进度的圆形进度条
最近项目有个需求,做带进度从下到上的圆形进度条. 网上查了一下资料,发现这篇博客写得不错http://blog.csdn.net/xiaanming/article/details/10298163 ...