您的位置:首页 > 其它

BZOJ 2337: [HNOI2011]XOR和路径( 高斯消元 )

2015-12-02 16:37 375 查看


一位一位考虑异或结果, f(x)表示x->n异或值为1的概率, 列出式子然后高斯消元就行了

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

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath> using namespace std; typedef long double ld;#define b(i) (1 << (i)) const int maxn = 109; ld mat[maxn][maxn];int N, deg[maxn]; struct edge { int to, w; edge* next;} E[20009], *pt = E, *head[maxn]; void AddEdge(int u, int v, int w) { deg[pt->to = v]++; pt->w = w; pt->next = head[u]; head[u] = pt++;} void Init() { memset(deg, 0, sizeof deg); int m; scanf("%d%d", &N, &m); N--; for(int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); u--; v--; AddEdge(u, v, w); if(u != v) AddEdge(v, u, w); }} 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[i][j], mat[r][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] -= t * mat[i][k]; } } for(int i = N; i--; ) { for(int j = i; ++j < N; ) mat[i]
-= mat[i][j] * mat[j]
; mat[i]
/= mat[i][i]; }} int main() { Init(); ld ans = 0; for(int i = 0; i < 30; i++) { memset(mat, 0, sizeof mat); for(int j = 0; j < N; j++) { for(edge* e = head[j]; e; e = e->next) if(e->to != N) { if(e->w & b(i)) mat[j][e->to]--, mat[j]
--; else mat[j][e->to]++; } else if(e->w & b(i)) mat[j]
--; mat[j][j] -= deg[j]; } Work(); ans += mat[0]
* b(i); } printf("%.3lf\n", (double) ans); return 0;}------------------------------------------------------------------

2337: [HNOI2011]XOR和路径

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 699 Solved: 390
[Submit][Status][Discuss]

Description



Input

Output

Sample Input

Sample Output

HINT

Source

Day2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: