bzoj3143 游走 期望dp+高斯消元
题意:
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
思路:很显然,我们肯定希望经过次数最多的边的标号最小,但是由于边的数量可能很多,而且好像也不存在什么很好转移的东西,那么我们就需要考虑点。
假设E[X]代表从x这个点出发的次数,那么对于{u,v}这样一条边的被经过的次数显然等于$\frac{E[u]}{deg[u]}+\frac{E[v]}{deg[v]}$ deg代表度数,也就是从其他点过来的概率。所以我们只要算出E[x]就可以完成这道题了。
我们考虑一般的u(除了起点和终点),显然易得$E[X]=\sum \frac {E[v]}{deg[v]}$。
而终点就是的E[X]就是0,起点的期望,除了上述的式子,还需要加入最初始的1.(游戏开局),由于我们这样可以得到n个式子,而且n个式子之间存在推来推去的关系,显然可以考虑高斯消元。
所以就按照上面这个式子高斯消元求解,然后把边按经过次数排序就是答案了。
#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
ll rd()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int maxn=;
const int inf=0x3f3f3f3f;
int T,n,m;
vector<int >ve[maxn];
struct edge{
int u,v;
double g;
friend bool operator<(const edge &a,const edge &b){
return a.g>b.g;
}
}e[maxn*maxn];
const double eps=1e-;
int equ=,var=;
double a[maxn][maxn],x[maxn],deg[maxn];
int Gauss()//高斯消元 返回 0 无解 返回 1有解
{
int i,j,k,col,max_r;
for(k=,col=;k<equ&&col<var;k++,col++)
{
max_r=k;
for(i=k+;i<equ;i++)
if(fabs(a[max_r][col])>fabs(a[max_r][col]))
max_r=i;
if(fabs(a[max_r][col])<eps) return ;
if(k!=max_r)
{
for(j=col;j<var;j++)
swap(a[k][j],a[max_r][j]);
swap(x[k],x[max_r]);
}
x[k]/=a[k][col];
for(j=col+;j<var;j++) a[k][j]/=a[k][col];
a[k][col]=;
for(i=;i<equ;i++)
{
if(i!=k)
{
x[i]-=x[k]*a[i][col];
for(j=col+;j<var;j++) a[i][j]-=a[k][j]*a[i][col];
a[i][col]=;
}
}
}
return ;
}
int main(){
cin>>n>>m;
rep(i,,m){
scanf("%d%d",&e[i].u,&e[i].v);
deg[e[i].u]++;
deg[e[i].v]++;
ve[e[i].u].push_back(e[i].v);
ve[e[i].v].push_back(e[i].u);
}
x[]=;
a[n-][n-]=;
equ=var=n+;
rep(i,,n-){
a[i-][i-]=;
//for(auto &v:ve[i]){
for(int j=;j<ve[i].size();j++){ int v=ve[i][j];
if(v!=n)
a[i-][v-]=-/deg[v];
}
}
Gauss();
for(int i=;i<=m;i++){
e[i].g=;
if(e[i].u!=n)
e[i].g+=x[e[i].u-]/deg[e[i].u];
if(e[i].v!=n)
e[i].g+=x[e[i].v-]/deg[e[i].v];
}
sort(e+,e++m);
double ans=;
rep(i,,m){
ans+=i*e[i].g;
}
printf("%.3f\n",ans);
}
bzoj3143 游走 期望dp+高斯消元的更多相关文章
- 【BZOJ3143】[Hnoi2013]游走 期望DP+高斯消元
[BZOJ3143][Hnoi2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 ...
- BZOJ3143: [Hnoi2013]游走(期望DP 高斯消元)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3597 Solved: 1618[Submit][Status][Discuss] Descript ...
- bzoj 3143 [Hnoi2013]游走 期望dp+高斯消元
[Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3394 Solved: 1493[Submit][Status][Disc ...
- 2018.09.23 bzoj3143: [Hnoi2013]游走(dp+高斯消元)
传送门 显然只需要求出所有边被经过的期望次数,然后贪心把边权小的边定城大的编号. 所以如何求出所有边被经过的期望次数? 显然这只跟边连接的两个点有关. 于是我们只需要求出两个点被经过的期望次数. 对于 ...
- BZOJ 3143: [Hnoi2013]游走 [概率DP 高斯消元]
一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分 ...
- BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...
- bzoj3143: [Hnoi2013]游走(贪心+高斯消元)
考虑让总期望最小,那么就是期望经过次数越多的边贪心地给它越小的编号. 怎么求每条边的期望经过次数呢?边不大好算,我们考虑计算每个点的期望经过次数f[x],那么一条边的期望经过次数就是f[x]/d[x] ...
- 期望dp+高斯消元——bzoj3143
比较经典的题,题解看网上的..https://www.cnblogs.com/GXZlegend/p/7054536.html 自己sort弄错了..还以为是高斯消元写歪了.. #include< ...
- 【noi2019集训题1】 脑部进食 期望dp+高斯消元
题目大意:有n个点,m条有向边,每条边上有一个小写字母. 有一个人从1号点开始在这个图上随机游走,游走过程中他会按顺序记录下走过的边上的字符. 如果在某个时刻,他记录下的字符串中,存在一个子序列和S2 ...
随机推荐
- tire 树入门
博客: 模板: 前缀是否出现: /* trie tree的储存方式:将字母储存在边上,边的节点连接与它相连的字母 trie[rt][x]=tot:rt是上个节点编号,x是字母,tot是下个节点编号 * ...
- Linux中目录结构以及VI编辑器常见的命令操作
1.每个目录的详细介绍,先放一张目录的整体结构在这里 /bin:是Binary的缩写,用于存放经常使用的命令 /sbin:s代表Super User,用于存放系统管理员使用的命令 /home:存放普通 ...
- haproxy的代理中继用法
背景: 现有: 一台baidu/ali/tecent云服务器A(地址为a.a.a.a); 一台VPS B(地址为b.b.b.b), B中搭建有ss,监听端口为8000. 需求: 一:使用A做跳板机访问 ...
- webpack output.publicPath
output.publicPath string function 对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片.文件等)来说,outpu ...
- git - Mac生成SSH key
步骤1.检查是否已经存在SSH Key 打开电脑终端,输入以下命令: ls -al ~/.ssh 会出现两种情况 步骤2. 生成/设置SSH Key 继续上一步可能出现的情况 (1)情况一: 终端出现 ...
- “二维数组”?
首先说明C中是不存在所谓的"多维数组"的. int array[a][b]:声明的是一个有a个元素的数组,每个数组元素是一个含b个元素的数组. 上述声明正确的说法是,数组的数组. ...
- table响应式设计
table不可用flex布局和td宽度的自适应. table外层加div.mml-table设置overflow-x:auto可以添加横向滚动条.
- Windows API 查看器
{ http://www.dependencywalker.com/ } { Download the latest version here: Download Version 2.2.6000 ...
- JQuery 浮动DIV显示提示信息并自动隐藏
/** * 浮动DIV定时显示提示信息,如操作成功, 失败等 * @param string tips (提示的内容) * @param int height 显示的信息距离浏览器顶部的高度 * @p ...
- java 获取的是本地的IP地址
1 public static void main(String[] args) { 2 try { 3 InetAddress address = InetAddress.getLocalHost( ...