BZOJ2337: [HNOI2011]XOR和路径

题解:

异或操作是每一位独立的,所以我们可以考虑每一位分开做。

假设当前正在处理第k位

那令f[i]表示从i到n 为1的概率。因为不是有向无环图(绿豆蛙的归宿),所以我们要用到高斯消元。

若有边i->j 权值为w,若w的k位为0,则f[i]+=1/du[i] * f[j],否则f[i]+=(1-f[j])/du[i]

注意我们现在在往回走,所以度数是i的而不是j的。

然后就可以高斯消元解出来了。

装X用模方程的lcm然后发现导致误差越来越大,WA出翔

代码:

  1 #include<cstdio>
  2   
  3 #include<cstdlib>
  4   
  5 #include<cmath>
  6   
  7 #include<cstring>
  8   
  9 #include<algorithm>
 10   
 11 #include<iostream>
 12   
 13 #include<vector>
 14   
 15 #include<map>
 16   
 17 #include<set>
 18   
 19 #include<queue>
 20   
 21 #include<string>
 22   
 23 #define inf 1000000000
 24   
 25 #define maxn 200+5
 26   
 27 #define maxm 200000+5
 28   
 29 #define eps 1e-10
 30   
 31 #define ll long long
 32   
 33 #define pa pair<int,int>
 34   
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36   
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38   
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40   
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42   
 43 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 44   
 45 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
 46   
 47 #define mod 1000000007
 48   
 49 using namespace std;
 50   
 51 inline int read()
 52   
 53 {
 54   
 55     int x=0,f=1;char ch=getchar();
 56   
 57     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 58   
 59     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 60   
 61     return x*f;
 62   
 63 }
 64 int n,m,k,tot,d[maxn],head[maxn];
 65 struct edge{int go,next,w;}e[maxm];
 66 inline void add(int x,int y,int w)
 67 {
 68     e[++tot]=(edge){y,head[x],w};head[x]=tot;
 69 }
 70 double ans,a[maxn][maxn];
 71 inline void gauss()
 72 {
 73     //for1(i,n){for1(j,n+1)cout<<a[i][j]<<' ';cout<<endl;}
 74     for1(i,n)
 75     {
 76         int k=i;
 77         for2(j,i+1,n)if(fabs(a[j][i])>fabs(a[k][i]))k=j;
 78         for2(j,i,n+1)swap(a[i][j],a[k][j]);
 79         for2(j,i+1,n)
 80         {
 81           double t=a[j][i]/a[i][i];
 82           for2(x,i,n+1)a[j][x]=a[i][x]*t-a[j][x];
 83         }
 84     }
 85     //for1(i,n){for1(j,n+1)cout<<a[i][j]<<' ';cout<<endl;}
 86     for3(i,n,1)
 87     {
 88         //cout<<a[i][i]<<' '<<a[i][n+1]<<"fuck"<<endl;
 89         for2(j,i+1,n)a[i][n+1]-=a[i][j]*a[j][n+1];
 90         a[i][n+1]/=a[i][i];
 91         //cout<<i<<' '<<a[i][n+1]<<endl;
 92     }
 93 }
 94   
 95 int main()
 96   
 97 {
 98     n=read();m=read();
 99     for1(i,m)
100     {
101         int x=read(),y=read(),w=read();
102         if(x!=y){d[x]++;d[y]++;add(x,y,w);add(y,x,w);}
103         else {d[x]++;add(x,x,w);}
104     }
105     for0(j,30)
106     {
107         memset(a,0,sizeof(a));
108         for1(x,n-1)
109         {
110             a[x][x]=-1.0;
111             double t=1.0/(double)d[x];
112             for4(i,x)
113             if(e[i].w>>j&1)a[x][n+1]-=t,a[x][y]-=t;
114             else a[x][y]+=t;
115         }
116         a[n][n]=1.0;
117         gauss();
118         //cout<<a[1][n+1]<<' '<<(1<<j)<<endl;
119         ans+=a[1][n+1]*(1<<j);
120     }
121     printf("%.3f\n",ans);
122   
123     return 0;
124   
125 }  
View Code

2337: [HNOI2011]XOR和路径

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 515  Solved: 281
[Submit][Status]

Description

posted @ 2015-01-19 17:21  ZYF-ZYF  Views(182)  Comments(0Edit  收藏  举报