BZOJ 3143: [Hnoi2013]游走( 高斯消元 )

我一开始的想法是设f(x)表示点x到N路径的期望长度, 那么f(u) = (∑f(v)+w(u,v)) / degreeu, f(N)=0, 我们代入入消元应该可以得到f(1)关于各条边长的关系式f(1)=∑we..然后贪心, 按照他们的系数来给边权...但是不会实现..但是我感觉是可行的..PoPoQQQ题解:http://blog.csdn.net/PoPoQQQ/article/details/42234607

-----------------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;

typedef pair<int, int> pii;

typedef long double ld;

const int maxn = 509;

ld mat[maxn][maxn], p[1000000];

int deg[maxn], N, M;

pii Eg[1000000];

struct edge {

int to;

edge* next;

} E[maxn * maxn], *pt = E, *head[maxn];

void AddEdge(int u, int v) {

deg[pt->to = v]++; pt->next = head[u]; head[u] = pt++;

}

void Init() {

memset(deg, 0, sizeof deg);

scanf("%d%d", &N, &M); N--;

for(int i = 0; i < M; i++) {

int u, v;

scanf("%d%d", &u, &v);

Eg[i] = make_pair(--u, --v);

AddEdge(u, v);

AddEdge(v, u);

}

}

void Work() {

for(int i = 0; i < N; i++) {

int r = i;

for(int j = i; ++j < N; )

if(fabs(mat[j][i]) > fabs(mat[r][i])) r = j;

if(r != i) {

for(int j = 0; j <= N; j++)

swap(mat[r][j], mat[i][j]);

}

for(int j = i; ++j < N; ) {

ld t = mat[j][i] / mat[i][i];

for(int k = i; k <= N; k++)

mat[j][k] -= mat[i][k] * t;

}

}

for(int i = N; i--; ) {

for(int j = i; ++j < N; )

mat[i][N] -= mat[i][j] * mat[j][N];

mat[i][N] /= mat[i][i];

}

}

bool Cmp(const ld &i, const ld &j) {

return i > j;

}

int main() {

freopen("test.in", "r", stdin);

freopen("test.out", "w", stdout);

Init();

memset(mat, 0, sizeof mat);

mat[0][N]--;

for(int i = 0; i < N; i++) {

for(edge* e = head[i]; e; e = e->next)

if(e->to != N) mat[i][e->to] += ld(1) / deg[e->to];

mat[i][i]--;

}

Work();

memset(p, 0, sizeof p);

for(int i = 0; i < M; i++) {

pii &t = Eg[i];

p[i] = mat[t.first][N] / deg[t.first] + mat[t.second][N] / deg[t.second];

}

sort(p, p + M, Cmp);

ld ans = 0;

for(int i = 0; i < M; i++)

ans += p[i] * (i + 1);

printf("%.3lf\n", (double) ans);

return 0;

}

-----------------------------------------------------------------------

3143: [Hnoi2013]游走

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1526  Solved: 660
[Submit][Status][Discuss]

Description

一个无向连通图,顶点从1编号到N,边从1编号到M。 
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。 
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。

Input

第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。

Output

仅包含一个实数,表示最小的期望值,保留3位小数。

Sample Input

3 3
2 3
1 2
1 3

Sample Output

3.333

HINT

边(1,2)编号为1,边(1,3)编号2,边(2,3)编号为3。

Source

非官方数据

时间: 2024-11-09 21:07:30

BZOJ 3143: [Hnoi2013]游走( 高斯消元 )的相关文章

BZOJ 3143 HNOI2013 游走 高斯消元 期望

这道题是我第一次使用高斯消元解决期望类的问题,首发A了,感觉爽爽的.... 中文题目,就不翻大意了,直接给原题: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. 输出最小的总分期望值. Solution: 这题贪心很明显

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

3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2264  Solved: 987[Submit][Status][Discuss] Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数

[BZOJ 3143][Hnoi2013]游走(高斯消元+期望)

Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. Solution 对于点u(u≠1):到达u的概率 f[u]=∑f[v]/d[v] (Edges(u,v)) 而f[1]=∑f[v]/d[v]+1

BZOJ 3143 HNOI2013 游走 期望DP+高斯消元

题目大意:给定一个无向连通图,我们需要给每条边附一个1~m的不重复的权值,使1到n的期望权值和最小 首先贪心思想是求出每条边的期望经过次数 然后对期望值最小的边附加m的权值,第二小的边附加m-1的权值,以此类推. 令f[i]为第i个点的期望经过次数 那么每条边的期望经过次数就是f[x]/d[x]+f[y]/d[y] 其中d[x]表示x的度数 那么显然有: f[1]=1+Σ[1->j]f[j]/d[j] f[i]=Σ[i->j]f[j]/d[j] (2<=i<=n-1) 其中f[n]

bzoj 3143 [Hnoi2013]游走【高斯消元+dp】

参考:http://blog.csdn.net/vmurder/article/details/44542575 和2337有点像 设点u的经过期望(还是概率啊我也分不清,以下都分不清)为\( x[u] \) ,度为 \( in[u] \),边\( (u,v) \) 的经过期望为 \( \frac{x[u]}{in[u]}+\frac{x[v]}{in[v]} \) 那么转换为求每个点的经过期望,\( x[u]=\sum_{v}^{v\subset son(u)}\frac{x[v]}{in[v

[BZOJ 3143][HNOI2013]游走(数学期望)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3143 分析: 易得如果知道了每条边经过的数学期望,那就可以贪心着按每条边的期望的大小赋值,所以问题就是如何求每条边的期望. 直接求没办法求的,可以先求出每个点经过的期望. 易得f[i]=∑f[j]/d[j] j->i有边 特殊的,对于起点,因为刚开始就在,所以应该是f[1]=1+∑f[j]/d[j]:对于终点,到了终点后不能再到其他节点,所以对其他边并没有贡献,所以f[n]=0 然后

●BZOJ 3143 [Hnoi2013]游走

题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3143题解: 期望dp,高斯消元 首先有这样一种贪心分配边的编号的方案:(然后我没想到,233) 我们按每一条边的期望经过次数去分配编号, 具体来说,就是期望经过次数越多的边,分配的编号越小,反之则编号越大. 然后问题转化为如何求一条边的期望经过次数.(把求边的期望转化为求点的期望) 我们定义cnt[i]表示i点的出度,dp[i]表示期望经过i点的次数. 然后对于一个边(u,v),期望经过该

bzoj 3143: [Hnoi2013]游走

高斯消元 对于边可能很多,那我们计录点的期望次数就行了. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8 #include<vector> 9 #define M 1009 10 #

【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元

[题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解]显然,应使经过次数越多的边编号越小,问题转化为求每条边的期望经过次数. 边数太多,容易知道f(u,v)=f(u)/out(u)+f(v)/out(v),所以转化为求每个点的期望经过次数,这就是驱逐猪猡了. 设f[x]表示点x的期望经过次数,根据全期望公式(讨论"经过"的问题不能依赖于下一步