1. 程式人生 > >BZOJ2337:[HNOI2011]XOR和路徑——題解

BZOJ2337:[HNOI2011]XOR和路徑——題解

.com art space urn include 期望 can png dash

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

——————————————————————————————————————————

http://www.lydsy.com/JudgeOnline/problem.php?id=2337

技術分享圖片

2 3 6

不會期望怎麽辦?看題解……

參考:http://blog.csdn.net/PoPoQQQ/article/details/42223843

我們考慮將xor的操作分解成對每一位的操作,然後將邊權拆成當前位,模擬xor操作即可。

剩下來的操作就和我的上一篇博客(BZOJ3143)基本上相同了。

#include<algorithm>
#include<iostream>
#include
<cstring> #include<cstdio> #include<cmath> using namespace std; typedef double dl; const int N=105; const int M=10005; struct node{ int to,nxt,w; }e[M*2]; int head[N],cnt,d[N]; inline void add(int u,int v,int w){ cnt++; e[cnt].to=v; e[cnt].w=w; e[cnt].nxt
=head[u]; head[u]=cnt; d[u]++; return; } dl c[N][N],f[N][N],x[N],ans; inline void Gauss(int n,int m){ for(int i=1;i<=n;i++){ int l=i; for(int j=l+1;j<=n;j++) if(fabs(f[l][i])<fabs(f[j][i]))l=j; if(l!=i) for(int j=i;j<=m;j++) swap(f[l][j],f[i][j]); for(int j=i+1;j<=n;j++){ dl temp=f[j][i]/f[i][i]; for(int k=i;k<=m;k++) f[j][k]=f[j][k]-f[i][k]*temp; } } for(int i=n;i>=1;i--){ dl t=f[i][m]; for(int j=n;j>i;j--) t-=x[j]*f[i][j]; x[i]=t/f[i][i]; } return ; } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); if(u!=v)add(v,u,w); } for(int i=0;i<=30;i++){ memset(f,0,sizeof(f)); memset(x,0,sizeof(x)); for(int u=1;u<n;u++){ for(int k=head[u];k;k=e[k].nxt){ int v=e[k].to,w=e[k].w; if(w&(1<<i))f[u][v]+=1,f[u][n+1]+=1; else f[u][v]-=1; } f[u][u]+=d[u]; } for(int j=1;j<=n+1;j++)f[n][j]=0; f[n][n]=1; Gauss(n,n+1); ans+=x[1]*(1<<i); } printf("%.3f\n",ans); return 0; }

BZOJ2337:[HNOI2011]XOR和路徑——題解