bzoj2115

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/syh0313/article/details/89206194

线性基

首先在1-n的任意一条路径上延伸出去的环可能对答案是有贡献的

所以我们把这些环找出来,然后丢到线性基里(防止它们的贡献相互抵消)

然后从线性基的最高位开始找起(有贡献就加入)

/**************************************************************

    Problem: 2115

    User: syh0313

    Language: C++

    Result: Accepted

    Time:720 ms

    Memory:38396 kb

****************************************************************/

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <cstring>

#include <algorithm>

using namespace std;

const int maxn=1000010;

int n,m,st[maxn],nt[maxn],to[maxn],topt,cnt;

long long w[maxn],p[70],a[maxn],dis[maxn],ans;

bool f[maxn];

void add(int x,int y,long long z)

{to[++topt]=y; nt[topt]=st[x]; st[x]=topt; w[topt]=z;}

void dfs(int x)

{

    f[x]=1; int p=st[x];

    while (p)

    {

        if (!f[to[p]]) {dis[to[p]]=dis[x]^w[p]; dfs(to[p]);}

         else if ((dis[x]^dis[to[p]]^w[p])!=0) a[++cnt]=dis[x]^dis[to[p]]^w[p];

        p=nt[p];

    }

}

int main()

{

    scanf("%d%d",&n,&m);

    for (int i=1;i<=m;i++)

    {

        int xx,yy; long long zz; scanf("%d%d%lld",&xx,&yy,&zz);

        add(xx,yy,zz); add(yy,xx,zz);

    }

    dfs(1); ans=dis[n];

    for (int i=1;i<=cnt;i++)

     for (int j=63;j>=0;j--)

      if ((a[i]>>j)&1)

      {

        if (!p[j]) {p[j]=a[i]; break;}

        a[i]^=p[j];

      }

    for (int i=63;i>=0;i--)

     if ((ans^p[i])>ans) ans^=p[i];

    printf("%lld\n",ans);

return 0;

}

猜你喜欢

转载自blog.csdn.net/syh0313/article/details/89206194