bzoj 2337: [HNOI2011]XOR和路徑


Description

給定一個無向連通圖,其節點編號為 1 到 N,其邊的權值為非負整數。試求出一條從 1 號節點到 N 號節點的路徑,使得該路徑上經過的邊的權值的“XOR 和”最大。該路徑可以重復經過某些節點或邊,當一條邊在路徑中出現多次時,其權值在計算“XOR 和”時也要被重復計算相應多的次數。
直接求解上述問題比較困難,於是你決定使用非完美算法。具體來說,從 1 號節點開始,以相等的概率,隨機選擇與當前節點相關聯的某條邊,並沿這條邊走到下一個節點,重復這個過程,直到走到 N 號節點為止,便得到一條從 1 號節點到 N 號節點的路徑。顯然得到每條這樣的路徑的概率是不同的並且每條這樣的路徑的“XOR 和”也不一樣。現在請你求出該算法得到的路徑的“XOR 和”的期望值。

solution

正解:高斯消元
根據期望的線性性,要求的東西可以拆成每一位二進制位的期望之和
考慮從i到達n時該二進制位為1的方案,分邊權是否為1討論:
\(f[j]+=f[i]/du[i]\) 如果邊權該位為0
\(f[j]+=(1-f[i])/du[i]\) 如果邊權的該位為1
考慮到這是有向圖,且存在環,所以不能拓撲序DP,用高斯消元可以解:
我們把 f[1],f[2]...f[n]看做是變量,然后du[i]看做是系數,就可以求了
但是做出來是WA的?一看題解仿佛必須要逆向推啊?原因仿佛是正推會存在不能走到i的概率?

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=105,M=20005;
int n,m,num=0,du[N],head[M],to[M],dis[M],nxt[M];
void link(int x,int y,int z){
	nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;}
double a[N][N],ans=0;
inline double solve(){
	for(int l=1;l<=n;l++){
		int maxid=l;
		for(int i=l+1;i<=n;i++)
			if(fabs(a[i][l])>fabs(a[maxid][l]))maxid=l;
		if(l!=maxid)swap(a[l],a[maxid]);
		for(int i=l+1;i<=n;i++){
			if(!a[i][l])continue;
			double tmp=a[l][l]/a[i][l];
			for(int j=l;j<=n+1;j++)
				a[i][j]=a[l][j]-tmp*a[i][j];
		}
	}
	for(int i=n;i>=1;i--){
		for(int j=i+1;j<=n;j++)
			a[i][n+1]-=a[i][j]*a[j][n+1];
		a[i][n+1]/=a[i][i];
	}
	return a[1][n+1];
}
void work()
{
	int x,y,z;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&z);
		link(x,y,z);du[y]++;
		if(x!=y)link(y,x,z),du[x]++;
	}
	for(int w=0;w<=30;w++){
		memset(a,0,sizeof(a));
		for(int i=1;i<n;i++){
			a[i][i]=1.0;
			for(int j=head[i];j;j=nxt[j]){
				int u=to[j];
				if(dis[j]&(1<<w))
					a[i][u]+=1.0/du[i],a[i][n+1]+=1.0/du[i];
				else a[i][u]-=1.0/du[i];
			}
		}
		a[n][n]=1.0;
		ans+=solve()*(1<<w);
	}
	printf("%.3lf\n",ans);
}

int main(){
	work();
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM