【bzoj3143】[Hnoi2013]游走 期望dp+高斯消元
2017-06-20 15:35
204 查看
题目描述
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
输入
第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。
输出
仅包含一个实数,表示最小的期望值,保留3位小数。
样例输入
3 3
2 3
1 2
1 3
样例输出
3.333
题解
期望dp+高斯消元
显然让期望经过次数越大的边编号越小即可,所以只要求出边的期望经过次数就能出解。
由于边数过大,但是边的期望经过次数可以用它连接的两个点的 期望次数/度数 之和得到,所以只要求出点的期望经过次数就能出解。
对于每个一般的点y,它的期望经过次数为$f[y]=\sum\limits_{exist\ x\to y}\frac{f[x]}{d[x]}$。
然后有两个特殊的点:1和n,由于1是起点,所以要算上初始经过的一次,在表达式的右边加1;由于n是终点,到达终点就不能够再经过其它边,所以按照上面的期望经过次数的计算方式,n的期望经过次数应该强制设置为0。(并非部分题解中的1)(所以其实上面的期望经过次数指的是“到达终点前的期望经过次数”,实际上也应该这样理解)
由于图是没有dp顺序的,所以需要使用高斯消元求出f[i]。
求出所有点的期望经过次数,然后计算出边的经过次数,排序出解。
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
输入
第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。
输出
仅包含一个实数,表示最小的期望值,保留3位小数。
样例输入
3 3
2 3
1 2
1 3
样例输出
3.333
题解
期望dp+高斯消元
显然让期望经过次数越大的边编号越小即可,所以只要求出边的期望经过次数就能出解。
由于边数过大,但是边的期望经过次数可以用它连接的两个点的 期望次数/度数 之和得到,所以只要求出点的期望经过次数就能出解。
对于每个一般的点y,它的期望经过次数为$f[y]=\sum\limits_{exist\ x\to y}\frac{f[x]}{d[x]}$。
然后有两个特殊的点:1和n,由于1是起点,所以要算上初始经过的一次,在表达式的右边加1;由于n是终点,到达终点就不能够再经过其它边,所以按照上面的期望经过次数的计算方式,n的期望经过次数应该强制设置为0。(并非部分题解中的1)(所以其实上面的期望经过次数指的是“到达终点前的期望经过次数”,实际上也应该这样理解)
由于图是没有dp顺序的,所以需要使用高斯消元求出f[i]。
求出所有点的期望经过次数,然后计算出边的经过次数,排序出解。
#include <cstdio> #include <cmath> #include <algorithm> #define N 510 using namespace std; struct data { int x , y; double p; }e[200010]; double a ; int n , map , d ; bool cmp(data a , data b) { return a.p > b.p; } void gauss() { int i , j , k; double t; for(i = 1 ; i <= n ; i ++ ) { for(k = i , j = i + 1 ; j <= n ; j ++ ) if(fabs(a[k][i]) < fabs(a[j][i])) k = j; for(j = 1 ; j <= n + 1 ; j ++ ) swap(a[i][j] , a[k][j]); for(j = i + 1 ; j <= n ; j ++ ) { t = a[j][i] / a[i][i]; for(k = i ; k <= n + 1 ; k ++ ) a[j][k] -= a[i][k] * t; } } for(i = n ; i >= 1 ; i -- ) { for(j = n ; j > i ; j -- ) a[i][n + 1] -= a[j][n + 1] * a[i][j]; a[i][n + 1] /= a[i][i]; } } int main() { int m , i , j; double ans = 0; scanf("%d%d" , &n , &m); for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &e[i].x , &e[i].y) , map[e[i].x][e[i].y] = map[e[i].y][e[i].x] = 1 , d[e[i].x] ++ , d[e[i].y] ++ ; for(i = 1 ; i < n ; i ++ ) { a[i][i] = 1; for(j = 1 ; j <= n ; j ++ ) if(map[j][i]) a[i][j] = -1.0 / d[j]; } a[1][n + 1] = a = 1; gauss(); for(i = 1 ; i <= m ; i ++ ) e[i].p = a[e[i].x][n + 1] / d[e[i].x] + a[e[i].y][n + 1] / d[e[i].y]; sort(e + 1 , e + m + 1 , cmp); for(i = 1 ; i <= m ; i ++ ) ans += e[i].p * i; printf("%.3lf\n" , ans); return 0; }
相关文章推荐
- 【BZOJ3143】[Hnoi2013]游走【高斯消元】【期望DP】【贪心】
- bzoj3143 [Hnoi2013]游走 (期望概率DP + 高斯消元)
- bzoj 3143: [Hnoi2013]游走 期望dp+高斯消元
- BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
- BZOJ 3143 HNOI2013 游走 期望DP+高斯消元
- 【BZOJ3143】[Hnoi2013]游走 期望DP+高斯消元
- 【BZOJ3143】【Hnoi2013】 游走 期望DP 高斯消元
- 【BZOJ 3143】 [Hnoi2013]游走 期望DP|高斯消元|贪心
- [期望DP+高斯消元] BZOJ3143: [Hnoi2013]游走
- BZOJ.3143.[HNOI2013]游走(概率 期望 高斯消元)
- [BZOJ]3143: [Hnoi2013]游走 期望+高斯消元
- bzoj 3143 [Hnoi2013]游走【高斯消元+dp】
- [BZOJ3143][Hnoi2013]游走(概率期望+高斯消元)
- BZOJ 3143: [Hnoi2013]游走 高斯消元 期望
- 【BZOJ3143】【Hnoi2013】游走 高斯消元 解期望方程
- [BZOJ3143][HNOI2013]游走(期望+高斯消元)
- bzoj 3143: [Hnoi2013]游走 (概率与期望+高斯消元)
- 【数学期望】【高斯消元】bzoj3143 [Hnoi2013]游走
- [BZOJ3143][Hnoi2013][概率与期望][高斯消元]游走
- bzoj 3143 [Hnoi2013]游走(贪心,高斯消元,期望方程)