【洛谷3232】[HNOI2013] 游走(贪心+高斯消元)
大致题意: 一个无向连通图,小\(Z\)从\(1\)号顶点出发,每次随机选择某条边走到下一个顶点,并将\(ans\)加上这条边的编号,走到\(N\)号顶点时结束。请你对边进行编号,使总分期望值最小。
一个贪心的思想
由于贪心的思想,我们肯定是给期望访问次数最大的边编号为\(1\),第二大的编号为\(2\),第三大的编号为\(3\),以此类推。
那么我们应该怎么求出边的期望呢?
由于边的期望可以由点的期望转化得来,因此只要求出了点的期望,就能求出边的期望。
那么怎么求出点的期望呢?
这时就需要用高斯消元了。
如何求出点的期望
下面是一张无向图。
如果我们用\(S_i\)来表示编号为\(i\)的节点被经过的期望次数,那么显然:
\]
即编号为\(x\)的点的期望\(S_x= \sum \frac{S_i}{deg_i}\),其中\(i\)为与\(x\)有边相连的节点。
像这样,我们可以将每一个点的期望都用其他点的期望来表示。
还是以\(S_1\)为例,我们可以将这个式子移项:
\]
将每个式子都进行这样的转换之后,就可以通过高斯消元来求解出每一个\(S_i\)。
其中要注意的是,每一个式子中\(S_n\)的系数皆为\(0\)(因为游走在走到\(n\)号节点时结束),且第\(1\)个式子等号右边的值为\(1\)(因为游走从\(1\)号节点开始),而其他式子等号右边的值皆为\(0\)。
从点的期望到边的期望
接下来的问题是,如何通过点的期望求出边的期望。
设\(E_i\)表示编号为\(i\)的边被经过的期望次数,且编号为\(i\)的边连接的两个节点为\(x_i\)和\(y_i\),由于期望的性质,我们可以得到:
\]
这样就可以轻松求出每条边的期望了。
然后,按照开头所述的贪心思想,就能轻松求解该题了。
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define N 500
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].from=x,e[ee].to=y,++deg[x])
char Fin[Fsize],*FinNow=Fin,*FinEnd=Fin;
using namespace std;
const double eps=1e-15;
int n,m,ee=0,lnk[N+5],deg[N+5];
struct edge
{
int from,to,nxt;
double val;
}e[N*N+5];
inline bool cmp(edge x,edge y)
{
return x.val-y.val>eps;
}
struct Gauss//高斯消元
{
double a[N+5][N+5],s[N+5];
inline void GetDataA(int x,int y,double v) {a[x][y]+=v;}
inline void GetDataS(int x,double v) {s[x]=v;}
inline void FindLine(int x)
{
register int i=x,j;register double t;
while(fabs(a[i][x])<eps) ++i;
for(t=s[i],s[i]=s[x],s[x]=t,j=1;j<=n;++j) t=a[i][j],a[i][j]=a[x][j],a[x][j]=t;
}
inline double GetAns()
{
register int i,j,k;register double delta,ans=0;
for(i=1;i<n-1;++i)
{
FindLine(i);
for(j=i+1;j<n;++j) for(s[j]+=(delta=-a[j][i]/a[i][i])*s[i],k=1;k<=n;++k) a[j][k]+=delta*a[i][k];
}
for(i=n-1;i;--i)
for(s[i]/=a[i][i],j=i-1;j;--j) s[j]-=a[j][i]*s[i];
for(i=2;i<=ee;++(++i)) e[i].val=s[e[i].from]/deg[e[i].from]+s[e[i].to]/deg[e[i].to];
for(sort(e+1,e+ee+1,cmp),i=1;i<=ee;++i) ans+=e[i].val*i;
return ans;
}
}S;
inline void read(int &x)
{
x=0;static char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));
}
int main()
{
register int i,j,x,y;
for(read(n),read(m),i=1;i<=m;++i) read(x),read(y),add(x,y),add(y,x);
for(i=1;i<n;++i) for(S.GetDataA(i,i,1),j=lnk[i];j;j=e[j].nxt) if(e[j].to^n) S.GetDataA(i,e[j].to,-1.0/deg[e[j].to]);//根据上面推导出的式子,初始化高斯消元的式子
return S.GetDataS(1,1),printf("%.3lf",S.GetAns()),0;//得出答案并输出
}
【洛谷3232】[HNOI2013] 游走(贪心+高斯消元)的更多相关文章
- 洛谷P3232 [HNOI2013]游走(高斯消元+期望)
传送门 所以说我讨厌数学……期望不会高斯消元也不会……好不容易抄好了高斯消元板子被精度卡成琪露诺了…… 首先,我们先算出走每一条边的期望次数,那么为了最小化期望,就让大的期望次数乘上小编号 边的期望次 ...
- [BZOJ3143][HNOI2013]游走(期望+高斯消元)
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3576 Solved: 1608[Submit][Status ...
- BZOJ3143 [Hnoi2013]游走 【高斯消元】
题目 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编 ...
- [luogu3232 HNOI2013] 游走 (高斯消元 期望)
传送门 题目描述 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等 ...
- [HNOI2013]游走 期望+高斯消元
纪念首道期望题(虽说绿豆蛙的归宿才是,但是我打的深搜总觉得不正规). 我们求出每条边的期望经过次数,然后排序,经过多的序号小,经过少的序号大,这样就可以保证最后的值最小. 对于每一条边的期望经过次数, ...
- 【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元
[题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解] ...
- bzoj 3143 [Hnoi2013]游走【高斯消元+dp】
参考:http://blog.csdn.net/vmurder/article/details/44542575 和2337有点像 设点u的经过期望(还是概率啊我也分不清,以下都分不清)为\( x[u ...
- 【BZOJ3143】游走(高斯消元,数学期望)
[BZOJ3143]游走(高斯消元,数学期望) 题面 BZOJ 题解 首先,概率不会直接算... 所以来一个逼近法算概率 这样就可以求出每一条边的概率 随着走的步数的增多,答案越接近 (我卡到\(50 ...
- 洛谷P3232[HNOI2013]游走
有一个无向简单连通图,顶点从 \(1\) 编号到 \(n\),边从 \(1\) 编号到 \(m\) 小Z在该图上进行随机游走,初始时小Z在\(1\)号顶点,每一步小Z以相等的概率随机选 择当前顶点的某 ...
- [bzoj3143] [洛谷P3232] [HNOI2013] 游走
Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...
随机推荐
- Python实现返回指定范围内的所有素数
# 获取a, b范围的所有素数 def func(a, b): li = [] for i in range(a, b+1): for j in range(2, i): if i % j == 0: ...
- 为什么MOBA和吃鸡类游戏不推荐用tcp协议 延迟不利于实时游戏
http://news.gamedog.cn/a/20171221/2287418.html 我们知道,不同类型的游戏因为玩法.竞技程度不一样,采用的同步算法不一样,对网络延迟的要求也不一样.例如,M ...
- thinphp5会员注册邮箱验证
1.首先完成邮箱发送http://www.cnblogs.com/jcydd/p/7299750.html 2.在完成会员新增后执行后置函数,在模型类当中 //注册后置函数 protected sta ...
- java日期与时间戳相互转换大全
转载大神 https://blog.csdn.net/djc777/article/details/50904989/
- @GeneratorValue与@GenericGenerator注解使用心得
参考博主们的 http://blog.csdn.net/tianxiezuomaikong/article/details/64930151
- maven 引入本地项目jar报红线错误解决方法
问题:本地创建了2个项目,A和B,A引入B,A的pom如下: <dependency> <groupId>com.ebc</groupId> <artifac ...
- notepad++的tab设置为4个空格
设置--首选项--语言--制表符设置--(勾选上)替换为空格
- Gym 100886J Sockets 二分答案 + 贪心
Description standard input/outputStatements Valera has only one electrical socket in his flat. He al ...
- xmanger图形化登陆远程服务器
由于网上的资料比较杂,经过本人整理实际操作验证,保证ok 本人的服务器系统为centos5.8 下面的都是centos服务器上的操作,需要简单的配置下: win客户端使用xmanger软件:首先是服 ...
- flask--数据库连接--URL
使用URL制定数据库 数据库引擎 URL MySQL mysql://username:password@hostname/database Postgres postgresql://usernam ...