zoukankan      html  css  js  c++  java
  • BZOJ 2115 【WC2011】 Xor

    Description

    Input

    第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。

    Output

    仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。

      这道题好像是很久以前学线性基的时候留下的……现在来填个坑……

      首先,由于异或有一个很好的性质,就是两个相同的数异或起来等于零。所以,一条边重复走两遍不会对答案产生贡献。这启示我们可以从一个点$u$走到点$v$,在$v$所在的一个环上走一圈,再走回到$u$,就可以得到$v$所在环的异或和。这样的话,我们就可以随意抠一条$1$到$n$的路径出来,假如异或和为$ans$,问题就转化这样了:有一个数$ans$和一些数(这些数就是每个环的异或和),可以选择是否异或上每个数,求$ans$的最大值。

      然后,我们要找出所有的环显然不现实。但是,我们可以发现所有环的异或和可以由一些环来得到。所以,在$dfs$的时候,一条非树边所连接的两个点加上这条非树边构成了一个环,我们把这种环全部找出来,所有环的异或和就都可以由这些环的异或和异或得到。所以,我们对这些异或和建立一个线性基,最后更新一下$ans$就可以了。

      下面贴代码(其实只有一遍$dfs$和一个线性基):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define maxn 50010
    #define maxm 200010
    
    using namespace std;
    typedef long long llg;
    
    int n,m,head[maxn],next[maxm],to[maxm],tt;
    llg c[maxm],dis[maxn],p[64],ans;
    bool vis[maxn];
    
    int getint(){
    	int w=0;bool q=0;
    	char c=getchar();
    	while((c>'9'||c<'0')&&c!='-') c=getchar();
    	if(c=='-') c=getchar(),q=1;
    	while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
    	return q?-w:w;
    }
    
    void link(int x,int y){
    	to[++tt]=y;next[tt]=head[x];head[x]=tt;
    	to[++tt]=x;next[tt]=head[y];head[y]=tt;
    	scanf("%lld",&c[tt]); c[tt-1]=c[tt];
    }
    
    void push(llg x){
    	for(int i=62;i>=0;i--)
    		if(x&(1LL<<i))
    			if(p[i]) x^=p[i];
    			else{p[i]=x;break;}
    }
    
    void dfs(int u,int fa){
    	vis[u]=1;
    	for(int i=head[u],v;v=to[i],i;i=next[i])
    		if(v!=fa)
    			if(!vis[v]) dis[v]=dis[u]^c[i],dfs(v,u);
    			else push(dis[u]^dis[v]^c[i]);
    }
    
    int main(){
    	File("a");
    	n=getint(); m=getint();
    	while(m--) link(getint(),getint());
    	dfs(1,0); ans=dis[n];
    	for(int i=62;i>=0;i--)
    		if((ans^p[i])>ans) ans^=p[i];
    	printf("%lld",ans);
    	return 0;
    }
  • 相关阅读:
    超酷图片压缩工具,就是不支持批量
    eclipse java热加载
    mysql 突然报错,连接不上
    svn问题终极解决办法
    svn经常困扰我的问题
    洛谷 P3628
    CodeForces 1091H
    委托的实际应用
    WPF 小知识点001
    C# 扩展方法一
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6066378.html
Copyright © 2011-2022 走看看