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

思路很精妙。好像能应用到很多地方。

发现如果路径上有环,可以通过一些走法达到 异或了那个环 或 没有异或那个环。

  所以路径上如果有环,可以把它们的异或值都存下来,之后随便挑选。

发现所有1~n的路径互相成环。

  这样就能随便找一条路径,然后把所有环的异或值存下来,用高斯消元随便挑选。

消元的时候尽量保留高位,而且要上下消,这样保留下来的每一行的首位就不会被其他行的挑选情况影响。

注意挑选的时候是取max,不是 | 什么的。

1.找环,可以先弄个生成树,然后每条非树边成环。也可以在dfs里顺便判断。

2.左移是 1ll !!!

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define ll long long
  5. using namespace std;
  6. const int N=5e4+,M=1e5+,LM=;
  7. int n,m,head[N],xnt=,tot,fa[N];
  8. ll dis[N],ml,a[M];
  9. bool vis[M<<],/*vis[N],*/flag;
  10. struct Ed{
  11. int next,fr,to;ll w;
  12. Ed(int n=,int f=,int t=,ll w=):next(n),fr(f),to(t),w(w) {}
  13. }ed[M<<];
  14. void add(int x,int y,ll z)
  15. {
  16. ed[++xnt]=Ed(head[x],x,y,z);head[x]=xnt;
  17. ed[++xnt]=Ed(head[y],y,x,z);head[y]=xnt;
  18. }
  19. int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
  20. void dfs(int cr,int f)
  21. {
  22. for(int i=head[cr],v;i;i=ed[i].next)
  23. if(vis[i]&&(v=ed[i].to)!=f)
  24. {
  25. dis[v]=(dis[cr]^ed[i].w);
  26. dfs(v,cr);
  27. }
  28. }
  29. void sc()
  30. {
  31. for(int i=;i<=n;i++)fa[i]=i;
  32. int lm=(m<<);
  33. for(int i=;i<=lm;i+=)
  34. if(find(ed[i].fr)!=find(ed[i].to))
  35. {
  36. vis[i]=vis[i^]=;fa[find(ed[i].fr)]=find(ed[i].to);
  37. }
  38. dfs(,);
  39. for(int i=;i<=lm;i+=) if(!vis[i])
  40. a[++tot]=(dis[ed[i].fr]^dis[ed[i].to]^ed[i].w);
  41. }
  42. //void dfs(int cr,int f)
  43. //{
  44. // vis[cr]=1;
  45. // for(int i=head[cr],v;i;i=ed[i].next)
  46. // if((v=ed[i].to)!=f)
  47. // if(!vis[v]){
  48. // dis[v]=(dis[cr]^ed[i].w);dfs(v,cr);
  49. // }
  50. // else a[++tot]=(dis[cr]^dis[v]^ed[i].w);
  51. //}
  52. int ws(ll x)
  53. {
  54. int ret=;for(;x;ret++)x>>=;return ret;
  55. }
  56. void gauss()
  57. {
  58. int now;
  59. for(int i=;i<=tot;i++)
  60. {
  61. if(!a[i])break;
  62. int nw=i;
  63. for(int j=i+;j<=tot;j++)if(a[j]>a[nw])nw=j;//>a[nw],不是a[i]...
  64. if(nw!=i)swap(a[i],a[nw]);
  65. now=ws(a[i])-;
  66. for(int j=;j<=tot;j++)if(i!=j&&(a[j]&(1ll<<now)))a[j]^=a[i];//上下消 //1ll
  67. }
  68. }
  69. //void gauss()
  70. //{
  71. // int nw=0;
  72. // for(int i=60;i>=0;i--)
  73. // {
  74. // int j=nw+1;
  75. // for(;j<=tot&&(a[j]&(1ll<<i))==0;j++);//1ll!!!
  76. // if(j==tot+1)continue;
  77. // nw++;
  78. // swap(a[nw],a[j]);
  79. // for(int j=1;j<=tot;j++)if(j!=nw&&(a[j]&(1ll<<i)))a[j]^=a[nw];
  80. // }
  81. //}
  82. int main()
  83. {
  84. scanf("%d%d",&n,&m);int x,y;ll z;
  85. for(int i=;i<=m;i++)
  86. {
  87. scanf("%d%d%lld",&x,&y,&z);add(x,y,z);
  88. }
  89. sc();/*dfs(1,0);*/ml=dis[n];//不用再dfs一遍求ml
  90. gauss();
  91. for(int i=;i<=tot;i++)ml=max(ml,ml^a[i]);//要这样!
  92. printf("%lld\n",ml);
  93. return ;
  94. }

bzoj 2115 [Wc2011] Xor——路径和环的转化的更多相关文章

  1. bzoj 2115 [Wc2011] Xor 路径最大异或和 线性基

    题目链接 题意 给定一个 \(n(n\le 50000)\) 个点 \(m(m\le 100000)\) 条边的无向图,每条边上有一个权值.请你求一条从 \(1\)到\(n\)的路径,使得路径上的边的 ...

  2. BZOJ 2115: [Wc2011] Xor

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 2794  Solved: 1184 [Submit][Stat ...

  3. BZOJ 2115: [Wc2011] Xor DFS + 线性基

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Description Input 第一行包含两个整数N和 M, 表示该无向图中 ...

  4. bzoj 2115: [Wc2011] Xor xor高斯消元

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 797  Solved: 375[Submit][Status] ...

  5. BZOJ 2115 Wc2011 Xor DFS+高斯消元

    标题效果:鉴于无向图.右侧的每个边缘,求一个1至n路径,右上路径值XOR和最大 首先,一个XOR并能为一个路径1至n简单的路径和一些简单的XOR和环 我们开始DFS获得随机的1至n简单的路径和绘图环所 ...

  6. BZOJ 2115: [Wc2011] Xor [高斯消元XOR 线性基 图]

    啦啦啦 题意: N 个点M条边的边带权的无向图,求1到n一条XOR和最大的路径 感觉把学的东西都用上了.... 1到n的所有路径可以由一条1到n的简单路径异或上任意个简单环得到 证明: 如果环与路径有 ...

  7. BZOJ.2115.[WC2011]Xor(线性基)

    题目链接 \(Description\) 给定一张无向带边权图(存在自环和重边).求一条1->n的路径,使得路径经过边的权值的Xor和最大.可重复经过点/边,且边权和计算多次. \(Soluti ...

  8. bzoj 2115: [Wc2011] Xor【线性基+dfs】

    -老是想到最长路上 其实可以这样:把每个环的xor和都存起来,然后任选一条1到n的路径的xor和ans,答案就是这个ans在环的线性基上跑贪心. 为什么是对的--因为可以重边而且是无相连通的,并且对于 ...

  9. BZOJ 2115 [Wc2011] Xor ——线性基

    [题目分析] 显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可. 但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有 ...

随机推荐

  1. 数据库自动增长id下一次的值

    mysql SELECT auto_increment FROM information_schema.`TABLES` WHERE TABLE_SCHEMA='my_db_name' AND TAB ...

  2. linux+udp+server+client

    一.客户端 #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include ...

  3. Centos7 搭建DNS服务器与原理配置详解

    在搭建我们自己DNS服务器之前,先必须了解下DNS服务器的作用和原理. DNS是在互联网上进行域名解析到对应IP地址的服务器,保存互联网上所有的IP与域名的对应信息,然后将我们对网址的访问,解析成IP ...

  4. CodeWars上的JavaScript技巧积累

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice The sli ...

  5. spark学习6(Centos下Scala2.11.4安装)

    Centos下Scala安装 上传Scala到/usr/scala目录下 [root@spark1 scala]# chmod u+x scala-2.11.4.tgz #修改权限 [root@spa ...

  6. Java -- JDBC 数据库连接池

    1. 原理代码示例 public class JdbcPool implements DataSource { private static LinkedList<Connection> ...

  7. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D. Generating Sets 贪心+优先队列

    D. Generating Sets time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  8. 安装rackspace private cloud --5 Deployment configuration

    运行Ansible playbooks之前,需要配置taget host Prerequisites . cp -r /opt/openstack-ansible/etc/openstack_depl ...

  9. Java-集合类源码List篇(二)

    前言 上篇中,我们分析了ArrayList的常用方法及其实现机制.ArrayList是基于内存空间连续的数组来实现的,List中其实还提供了一种基于链表结构的LinkedList来实现集合.同时多线程 ...

  10. js装饰者模式

    装饰者模式是为已有的功能动态地添加更多功能的一种方式.当系统需要新功能的时候,是向旧的类中添加新的代码.这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑, ...