BZOJ 2115 Xor【线性基+dfs】

https://www.lydsy.com/JudgeOnline/problem.php?id=2115

这个问题可以理解成找一条从1~n的路径,然后不停的在上面加环使得最后的总权值最大。

因为如果是死胡同,进去出来没有任何贡献,如果一个环和原来的路径重复,那么也并没有什么影响。只不过相当于原来的那条路多走了一遍,又被清掉了,没有什么需要额外讨论的。不同的环可以通过线性基来处理!

WA点:运算符优先级。

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
const int maxn=1e5+23;
struct node{
int to,nx;ll w;}e[maxn];
int vis[maxn];
int head[maxn];
ll b[80];
ll d[maxn];
ll c[maxn];
int sz,cs;
void add(int u,int v,ll w){
    e[++sz].to=v;
    e[sz].nx=head[u];
    e[sz].w=w;
    head[u]=sz;
}
void dfs(int x){
    vis[x]=1;
    for(int i=head[x];i!=-1;i=e[i].nx){
        int v=e[i].to;
        if(!vis[v]){
            d[v]=d[x]^e[i].w;dfs(v);
        }
        else{
            c[++cs]=d[x]^d[v]^e[i].w;
        }
    }
}
int main()
{
    sz=0;cs=0;
    memset(vis,0,sizeof vis);
    memset(head,-1,sizeof head);
    memset(d,0,sizeof d);
    int n,m;
    scanf("%d %d",&n,&m);int u,v;ll w;
    for(int i=1;i<=m;i++){
        scanf("%d%d%lld",&u,&v,&w);
        add(u,v,w);
    }
    //cout<<e[7].w;
    dfs(1);
   // cout<<1<<endl;
    ll ans=d[n];
    for(int i=1;i<=cs;i++){
        for(int j=63;j>=0;j--){
            if(!(c[i]>>j)) continue;
            if(!b[j]){
                b[j]=c[i];break;
            }
            c[i]^=b[j];
        }
    }
    for(int i=63;i>=0;i--){
        if((ans^b[i])>ans) ans=ans^b[i];
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/irish_moonshine/article/details/81145537