您的位置:首页 > 其它

[BZOJ 2337][HNOI2011]XOR和路径

2016-03-25 14:55 267 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2337

高斯消元解期望方程。

按位考虑

首先从n出来的边不能算!

然后期望要倒着推

因为我们不知道1到n的期望但是我们知道n到n的期望

并且xor的期望≤1

则有if(dis==0)E(u)=∑E(v)/deg[u]

elseE(u)=∑(1−E(v))/deg[u]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
using namespace std;

int n, m;

struct Edge{int u, v, dis;};

Edge edge[maxn], G[maxn];

int cnt, deg[maxn];

void add(int u, int v, int w){
cnt ++;
edge[cnt].v = v;
edge[cnt].u = u;
edge[cnt].dis = w;
deg[u] ++;
}

double a[110][110];

void Gauss(int n){
for(int i = 1; i <= n; i ++){
for(int j = i; j <= n; j ++){
if(a[j][i]){
for(int k = 1; k <= n+1; k ++)
swap(a[i][k], a[j][k]);
for(int k = 1; k <= n+1; k ++)
if(k != i)a[i][k] /= a[i][i];
a[i][i] = 1;
break;
}
}
if(a[i][i] == 0)continue;
for(int j = 1; j <= n; j ++){
if(j == i || a[j][i] == 0)continue;
double t = a[j][i];
for(int k = i; k <= n+1; k ++)
a[j][k] -= t * a[i][k];
}
}
}

void Debug(int n){
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n+1; j ++)
printf("%.2lf ", a[i][j]);
printf("\n");
}puts("");
}

double solve(int p){
memset(a, 0, sizeof a);

/*
if(dis == 1)E(u) = E(v) * 1/deg[u]
else E(u) = (1 - E(v)) * 1/deg[u]
*/
for(int i = 1; i <= n; i ++)a[i][i] = 1;
for(int i = 1; i <= cnt; i ++){
int u = edge[i].u, v = edge[i].v;
if(u == n)continue;
if(edge[i].dis >> p & 1){
a[u][v] += 1.0 / deg[u];
a[u][n+1] += 1.0 / deg[u];
}
else a[u][v] -= 1.0 / deg[u];
}

Gauss(n);
return a[1][n+1];
}

int main(){
scanf("%d%d", &n, &m);
int u, v, w;
for(int i = 1; i <= m; i ++){
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
if(v != u)add(v, u, w);
}
double ans = 0;
for(int i = 30; i >= 0; i --)
ans += solve(i) * (1 << i);
printf("%.3lf\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: