zoukankan      html  css  js  c++  java
  • bzoj2115[WC2011]Xor

    题意

    选出一条从1到n的路径(可以不是简单路径),使得其上边权异或和最大.

    分析

    快退役了,抓紧涨一下bzoj题量.
    任意找出一条从1到n的路径,另外一条从1到n的路径一定可以表示成这条路径异或上若干个环.所以dfs找出所有dfs树上反向边,跑线性基,贪心求最大值即可.
    那么这篇题解主要是记录一下自己的脑残...我的写法把每个环算了两次,意识到这点后我这样想:既然是连通图,dfs树上有n-1条树边,m-(n-1)条非树边,极限数据点数50000,边数100000,有100000-(50000-1)=50001条非树边,一条边算两次,那么开100005的数组也完全够了.然后RuntimeError根本停不下来...
    实际上是这样:边数取到100000时,点数可以不取到50000,这样极限情况下我大约需要200000多一点的数组...
    怎么还有这种RuntimeError

    #include<cstdio>
    #include<cstring>
    typedef unsigned long long ul;
    const int maxn=50005,maxm=100005;
    struct edge{
      int to,next;ul w;
    }lst[maxm<<1];int len=0,first[maxn];
    void addedge(int a,int b,ul w){
      lst[len].to=b;lst[len].next=first[a];lst[len].w=w;first[a]=len++;
    }
    bool vis[maxn];
    ul w[maxm];
    ul cir[maxm<<1];
    int tot=0;
    int prt[maxn],dfn[maxn];
    void dfs(int x){
      vis[x]=true;
      for(int pt=first[x];pt!=-1;pt=lst[pt].next){
        if(!vis[lst[pt].to]){
          w[lst[pt].to]=w[x]^lst[pt].w;
          prt[lst[pt].to]=pt;
          dfs(lst[pt].to);
        }else if(pt!=(prt[x]^1)){
          cir[++tot]=w[lst[pt].to]^w[x]^lst[pt].w;
        }
      }
    }
    ul b[70];
    void getbase(){
      ul* a=cir;
      for(int i=1;i<=tot;++i){
        for(int j=60;j>=0;--j){
          if(a[i]>>j&1){
    	if(b[j])a[i]^=b[j];
    	else{
    	  b[j]=a[i];
    	  for(int k=j-1;k>=0;--k)if(b[k]&&(b[j]>>k&1))b[j]^=b[k];
    	  for(int k=j+1;k<=60;++k)if(b[k]>>j&1)b[k]^=b[j];
    	  break;
    	}
          }
        }
      }
    }
    int main(){
      memset(first,-1,sizeof(first));
      int n,m;scanf("%d%d",&n,&m);
    
      for(int i=1;i<=m;++i){
        int a,b;ul w;
        scanf("%d%d%llu",&a,&b,&w);
        if(a==b)cir[++tot]=w;
        else{
          addedge(a,b,w);
          addedge(b,a,w);
        }
      }
      dfs(1);
      getbase();
      for(int j=60;j>=0;--j){
        if(b[j]&&(!(w[n]>>j&1)))w[n]^=b[j];
      }
      printf("%llu
    ",w[n]);
      return 0;
    }
    
  • 相关阅读:
    ora-01034 ora-27101解决方法(亲测)
    windows C++内存检测
    oracle求特定字符的个数
    ORACLE查看并修改最大连接数
    你必须用角色管理工具安装Microsoft .NET Framework 3.5
    让VC编译的Release版本程序在其他机器上顺利运行
    创建数据库连接
    C++ 判断进程是否存在
    excel
    毕设学习笔记
  • 原文地址:https://www.cnblogs.com/liu-runda/p/7156544.html
Copyright © 2011-2022 走看看