【BZOJ2337】[HNOI2011]XOR和路径 期望DP+高斯消元

【BZOJ2337】[HNOI2011]XOR和路径

Description

题解:异或的期望不好搞?我们考虑按位拆分一下。

我们设f[i]表示到达i后,还要走过的路径在当前位上的异或值得期望是多少(妈呀好啰嗦),设d[i]表示i的度数。然后对于某条边(a,b),如果它的权值是1,那么f[b]+=(1-f[a])/d[a];如果它的权值是0,那么f[b]+=f[a]/d[a],然后我们移个项,就变成了一堆方程组求解,直接高斯消元。

别忘了f[n]=0!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
typedef long double ld;
int d[110];
ld v[110][110],ans;
int n,m;
int pa[10010],pb[10010],pc[10010];
ld calc(int x)
{
	int i,j,k;
	for(i=1;i<=n;i++)	for(j=1;j<=n+1;j++)	v[i][j]=0;
	for(i=1;i<=m;i++)
	{
		if(pc[i]&x)
		{
			v[pa[i]][pb[i]]+=1,v[pa[i]][n+1]+=1;
			if(pa[i]!=pb[i])	v[pb[i]][n+1]+=1,v[pb[i]][pa[i]]+=1;
		}
		else
		{
			v[pa[i]][pb[i]]-=1;
			if(pa[i]!=pb[i])	v[pb[i]][pa[i]]-=1;
		}
	}
	for(i=1;i<=n;i++)	v[i][i]+=d[i];
	for(i=1;i<=n+1;i++)	v[n][i]=0;
	v[n][n]=1;
	for(i=1;i<=n;i++)
	{
		for(j=i;j<=n;j++)	if(fabs(v[i][i])<fabs(v[j][i]))	for(k=i;k<=n+1;k++)	swap(v[i][k],v[j][k]);
		if(fabs(v[i][i])<1e-7)	continue;
		for(j=n+1;j>=i;j--)	v[i][j]/=v[i][i];
		for(j=1;j<=n;j++)	if(i!=j)
		{
			for(k=1;k<=n+1;k++)	if(k!=i)	v[j][k]-=v[j][i]*v[i][k];
			v[j][i]=0;
		}
	}
	return v[1][n+1];
}
int main()
{
	int i,a,b,c;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&pa[i],&pb[i],&pc[i]);
		d[pa[i]]++;
		if(pa[i]!=pb[i])	d[pb[i]]++;
	}
	for(i=1;i<1<<30;i<<=1)	ans+=i*calc(i);
	printf("%.3lf",(double)ans);
	return 0;
}
时间: 2024-11-25 13:54:12

【BZOJ2337】[HNOI2011]XOR和路径 期望DP+高斯消元的相关文章

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]

【BZOJ3143】[Hnoi2013]游走 期望DP+高斯消元

[BZOJ3143][Hnoi2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数.当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和. 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小. Input 第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v

BZOJ 3270 博物馆 期望DP+高斯消元

题目大意:给定一张无向连通图,两个人初始各在某个点上,每个时刻每个人会不动或任选出边走,求两人最终期望在哪里相遇 把点数平方,原图上的两个点(x,y)变成新图上的一个点 然后令A为这个图的邻接矩阵(若两人在同一点上则没有出边,否则按概率转移),S为初始行向量(S[(a,b)]=1),ans为答案行向量 那么有ans=S+SA+SA^2+SA^3+... =S(I-A^+∞)/(I-A) =S/(I-A) 于是有ans*(I-A)=S 于是对I-A的转置求高斯消元即可. 和驱逐猪猡那题的思路很像.

期望dp+高斯消元+bfs——hdu4418

高斯消元又弄了半天.. 注意只要能建立矩阵,那就必定有解,所以高斯消元里可以直接return 1 #include<bits/stdc++.h> using namespace std; const int maxn = 205; const double esp = 1e-7; int n,m,x,y,d; double p[maxn],a[maxn][maxn],b[maxn]; int equ,var; int Gauss(){ for(int i=0;i<n;i++){ int

【期望DP+高斯消元】 UVA 10828 Back to Kernighan-Ritchie

通道 题意:从1开始 每次等概率从一个点到和他相邻的点 有向 走到不能走停止 求停止时每个点的期望

【期望DP+高斯消元】 HDU 4418 Time travel

通道 题意:1个人在数轴上来回走,以pi的概率走i步i∈[1, m],给定n(数轴长度),m,e(终点),s(起点),d(方向),求从s走到e经过的点数期望 思路:E[x] = sum((E[x+i]+i) * p[i])(i∈[1, m]) ,(走i步经过i个点,所以是E[x+i]+i) E[x] = sum ((E[x+i]+i) * p[i])----> E[x] - sum(p[i]*E[x+i]) = sum(i*p[i]) 代码: #include <iostream> #i

BZOJ 1778 Usaco2010 Hol Dotp 驱逐猪猡 期望DP+高斯消元

题目大意:给定一个无向图,炸弹从1号节点出发,每个时刻有P/Q的概率爆炸,如果某个时刻没有爆炸,就会等概率沿着随机一条出边走到下一个城市,求最终每个城市的爆炸概率 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 330 using namespace std; int n,m,p,q;

2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)

题目链接 题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的那个去做,问她最终有一个账号达到1000分需要做的比赛的次数的期望值. 思路 :可以直接用公式推出来用DP做,也可以列出210个方程组用高斯消元去做. (1)DP1:离散化.因为50,100,1000都是50的倍数,所以就看作1,2,20.这样做起来比较方便. 定义dp[i]为从 i 分数到达i+1

【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接.保证城市1至少连接一个其它的城市.一开始臭气弹会被放在城市1.每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <