bzoj2337 XOR和路径——高斯消元

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2337

异或就一位一位考虑;

x为到n的概率,解方程组即可;

考虑了n就各种蜜汁错误,所以索性不管n了,这样的题好像不管n比较方便。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int const M=10005;
int n,m,d[105],head[105],ct;
double a[105][105],ans,x[105];
struct N{
    int to,next,w;
    N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {}
}edge[M<<1];
void add(int x,int y,int z)
{
    edge[++ct]=N(y,head[x],z);head[x]=ct;
    d[x]++;
}
void gauss()
{
    for(int i=1;i<n;i++)
    {
        int k=i;
        for(int j=i+1;j<n;j++)
            if(fabs(a[j][i])>fabs(a[k][i]))k=j;
        if(k!=i)
            for(int j=i;j<=n+1;j++)swap(a[k][j],a[i][j]);
        for(int j=n+1;j>=i;j--)a[i][j]/=a[i][i];
        for(int j=i+1;j<n;j++)
            for(int l=n+1;l>=i;l--)//倒序!!! 
                a[j][l]-=a[j][i]*a[i][l];
    }
    for(int i=n-1;i;i--)
    {
        for(int j=i+1;j<n;j++)//不是n+1 
            a[i][n+1]-=a[i][j]*x[j];
        x[i]=a[i][n+1];
    }
}
void work(int nw)
{
    memset(a,0,sizeof a);
    memset(x,0,sizeof x);
    for(int i=1;i<n;i++)
    {
        for(int j=head[i];j;j=edge[j].next)
        {
            int to=edge[j].to;
            int w=edge[j].w;
            if(w&nw)a[i][to]-=1.0/d[i],a[i][n+1]-=1.0/d[i];
            else a[i][to]+=1.0/d[i];
        }
        a[i][i]-=1;
    }
    gauss();
    ans+=x[1]*nw;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,x,y,z;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        if(x!=y)add(y,x,z);
    }
    for(int i=0;i<=30;i++)
        work(1<<i);
    printf("%.3lf",ans);
    return 0;
}

 

posted @ 2018-05-17 19:06  Zinn  阅读(140)  评论(0编辑  收藏  举报