Description

在米国有一所大学,名叫万国歌剧与信息大学(UniversalOperaandInformaticasUniversity)。简称UOI大学。UO
I大学的建筑与道路分布很有趣,每对建筑之间有且仅有一条直接或者间接的路径相连,更加明确的说,就是成树
形分布。其实在设计时,对于大学的N个建筑,总共有M条道路可以修建,每条道路都有一个距离值Disti和一个美
学值Valuei。一个设计方案的距离值和美学值定义为该设计方案内包含的道路的距离值与美学值之和。投资方的要
求只有设计方案的距离值最小。大神出于对树的喜爱所以决定设计方案必须是一棵树。因为要参加UOI,所以当时
大神就急急忙忙地随机选择了一个合法的方案。但其实存在很多合法的方案,假设每种设计方案取的概率是均等的
,那么设计方案的美学值期望是多少?

Input

第一行两个整数,N和M,意义如上所述。
第二行到第M+1行,每行4个整数,Xi,Yi,Disti,Valuei,分别表示这条道路连接的
两个建筑的编号,距离值以及美学值。
输入保证至少有一种合法方案。
100%的数据保证N<=10000M<=200000
100%的数据保证距离值相同的道路数小于30,同时不保证没有重边。

Output

一行一个整数,即满足总道路长度最小的情况下,设计方案的美学值期望。要求保留5位小数

按边权升序加边同时缩点,忽略缩点产生的自环,对同一权值且 加入此权值的边后在同个联通块内 的一组边,用矩阵树定理计算出生成树个数以及删去每条边后的生成树个数,于是可得一条边在最小生成树中的概率,统计答案。似乎要用long double才能过,但计算行列式时无论用long double还是模意义下的整数计算都能过。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long double ld;
#define double ld
int _(){
int x=,c=getchar(),f=;
while(c<)c=='-'&&(f=-),c=getchar();
while(c>)x=x*+c-,c=getchar();
return x*f;
}
int es[],enx[],e0[],ep=,ev[];
struct edge{
int a,b,c,d;
void init(){
a=_();b=_();c=_();d=_();
}
void adde(){
es[ep]=b;enx[ep]=e0[a];ev[ep]=d;e0[a]=ep++;
es[ep]=a;enx[ep]=e0[b];ev[ep]=d;e0[b]=ep++;
}
}e[];
bool operator<(edge a,edge b){
return a.c<b.c;
}
double ans=;
int n,m,f[],id[],idp=,idt[],tk=,ed[],ID[],IDP;
int v[][],v1,ee[][],eep,os[][],op=;
int get(int x){
int a=x,c;
while(x!=f[x])x=f[x];
while(x!=f[a])c=f[a],f[a]=x,a=c;
return x;
}
void gid(int x){
if(idt[x]!=tk)idt[x]=tk,id[x]=++idp;
}
void dfs(int w){
if(ed[w]!=tk)ed[w]=tk,ID[w]=++IDP;
for(int i=e0[w],u;i;i=enx[i]){
u=es[i];
if(ed[u]!=tk)dfs(u);
if(ID[w]<ID[u]){
++v[ID[w]][ID[w]];
++v[ID[u]][ID[u]];
--v[ID[w]][ID[u]];
--v[ID[u]][ID[w]];
ee[eep][]=ID[w];
ee[eep][]=ID[u];
ee[eep++][]=ev[i];
}
}
}
const double _0=1e-;
double solve(int n){
static double a[][];
double s=;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
a[i][j]=v[i][j];
for(int i=;i<=n;++i){
if(fabs(a[i][i])<_0){
int t=i;
for(int j=i+;j<=n;++j)if(fabs(a[j][i])>fabs(a[t][i]))t=j;
if(fabs(a[t][i])<_0)return ;
for(int j=i;j<=n;++j)swap(a[i][j],a[t][j]);
}
for(int j=i+;j<=n;++j)if(a[j][i]){
double x=a[j][i]/a[i][i];
for(int k=i;k<=n;++k)a[j][k]-=x*a[i][k];
}
}
for(int i=;i<=n;++i)s*=a[i][i];
return s;
}
void chk(int x){
if(ed[x]==tk)return;
IDP=;++tk;eep=;
dfs(x);
double v0=solve(IDP-);
for(int i=;i<eep;++i){
int x=ee[i][],y=ee[i][];
--v[x][x],--v[y][y],++v[x][y],++v[y][x];
double v1=v0-solve(IDP-);
ans+=v1/v0*ee[i][];
++v[x][x],++v[y][y],--v[x][y],--v[y][x];
}
for(int i=;i<=IDP;++i){
for(int j=;j<=IDP;++j)v[i][j]=;
}
}
int main(){
n=_();m=_();
for(int i=;i<=n;++i)f[i]=i;
for(int i=;i<m;++i)e[i].init();
std::sort(e,e+m);
for(int i=,j=;i<m;){
for(++tk,idp=;j<m&&e[i].c==e[j].c;++j);
for(int k=i;k<j;++k){
int x=get(e[k].a),y=get(e[k].b);
if(x==y){
e[k].a=-;
continue;
}
os[op][]=e[k].a;os[op++][]=e[k].b;
gid(x);gid(y);
e[k].a=id[x];
e[k].b=id[y];
e[k].adde();
}
while(op)--op,f[get(os[op][])]=get(os[op][]);
for(;i<j;++i)if(~e[i].a){
chk(e[i].a);
chk(e[i].b);
}
for(int t=;t<=idp;++t)e0[t]=;
ep=;
}
printf("%.5Lf",ans);
return ;
}

bzoj4637: 期望的更多相关文章

  1. 【BZOJ4637】期望 Kruskal+矩阵树定理

    [BZOJ4637]期望 Description 在米国有一所大学,名叫万国歌剧与信息大学(UniversalOperaandInformaticasUniversity).简称UOI大学.UOI大学 ...

  2. bzoj4637:期望

    思路:最小生成树计数只不过加了一个期望,由于期望具有线性性质,就可以转化为每条边的期望之和,那么一条边的期望如何求呢,在最小生成树记数中,是把相同边权的一起处理,之后把属于连通块内的点缩点,也就是说, ...

  3. 【BZOJ-3143】游走 高斯消元 + 概率期望

    3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2264  Solved: 987[Submit][Status] ...

  4. bzoj1415[NOI2005]聪聪和可可-期望的线性性

    这道题之前我写过一个巨逗比的写法(传送门:http://www.cnblogs.com/liu-runda/p/6220381.html) 当时的原因是这道题可以抽象出和"绿豆蛙的归宿&qu ...

  5. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  6. 【BZOJ3036】绿豆蛙的归宿 概率与期望

    最水的概率期望,推荐算法合集之<浅析竞赛中一类数学期望问题的解决方法> #include <iostream> #include <cstdio> using na ...

  7. UVA&&POJ离散概率与数学期望入门练习[4]

    POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...

  8. 【BZOJ-1426】收集邮票 概率与期望DP

    1426: 收集邮票 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 261  Solved: 209[Submit][Status][Discuss] ...

  9. 【BZOJ-1419】Red is good 概率期望DP

    1419: Red is good Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 660  Solved: 257[Submit][Status][Di ...

随机推荐

  1. Git简易的命令行入门教程

    简易的命令行入门教程: Git 全局设置: git config --global user.name "imsoft" git config --global user.emai ...

  2. 简单实用的纯CSS百分比圆形进度条插件

    percircle是一款简单实用的纯CSS百分比圆形进度条插件.你不需要做任何设置,只需要按该圆形进度条插件提供的标准HTML结构来编写代码,就可以生成一个漂亮的百分比圆形进度条. 首先要做的就是引入 ...

  3. android中的空格及汉字的宽度

    在Android布局中进行使用到空格,以便实现文字的对齐.那么在Android中如何表示一个空格呢? 空格:  窄空格:  一个汉字宽度的空格:   [用两个空格(  )占一个汉字的宽度时,两个空格比 ...

  4. numpy常用函数

    numpy.ndarray.astype  更改np.array的类型.

  5. java加密与解密

    1.下载:UnlimitedJCEPolicy    主要:获取权限文件2.把解压后的      local_policy.jar      US_export_policy.jar   复制到 这个 ...

  6. IOS 开发qq登陆界面

    // //  ViewController.m //  QQUI_bydfg // //  Created by Kevin_dfg on 16/4/15. //  Copyright © 2016年 ...

  7. Linux系统编程@进程管理(二)

    1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...

  8. vi基本操作

    vi的基本操作 a) 进入vi 在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面: $ vi myfile 不过有一点要特别注意,就是您进入vi之后,是处于「命令行模式(command m ...

  9. 高斯混合模型参数估计的EM算法

    # coding:utf-8 import numpy as np def qq(y,alpha,mu,sigma,K,gama):#计算Q函数 gsum=[] n=len(y) for k in r ...

  10. OC IOS屏幕分辨率

    CGRect screenRect=[UIScreenmainScreen].bounds; CGSize screenSize=screenRect.size; //屏幕分辨率 screenSize ...