【WC2011】最大xor路径

【WC2011】最大xor路径

考虑一个边权为非负整数的无向连通图,节点编号为 1 到 N,试求出一条从 1 号节点到 N 号节点的路径,使得路径上经过的边的权值的 XOR 和最大。

路径可以重复经过某些点或边,当一条边在路径中出现了多次时,其权值在计算 XOR 和时也要被计算相应多的次数.

       重要性质(or 结论):如果一个链和一个环异或,那么链与环连接的路径必定被经过两次,故连接路径异或值为0,相当于异或了一个环。

      所以可以先把所有环加进线性基中,然后随意选一条链作为路径开始,之后有更大的链异或两条链组成的环即可。

       顺便我还是太蒻了,先写错前向星又写错线性基orz,然后就调了一晚上)。

       

 1 #include<bits/stdc++.h>
 2 #define re register int
 3 #define LL long long 
 4 #define maxn 200000+5
 5 #define maxn2 50000+5
 6 using namespace std;
 7 int n,m;
 8 int cnt;
 9 int head[maxn2];
10 LL vaa[maxn2];
11 bool vis[maxn2];
12 LL lin[70];
13 struct edge{
14     int nex,to;
15     LL w;
16 }ed[maxn];
17 void add(int u,int v,LL va){
18     ed[++cnt].to=v;
19     ed[cnt].w=va;
20     ed[cnt].nex=head[u];
21     head[u]=cnt;
22 }
23 void insert(LL x)
24 {
25     for(re i=63;i>=0;i--){
26         if((x>>i)&1) {
27     if(!lin[i]) {
28         lin[i]=x;
29         return;
30     }
31         else x^=lin[i];
32     }
33 }
34 }
35 void dfs(int u,LL val)
36 {
37     vaa[u]=val;
38     vis[u]=true;
39     for(re i=head[u];i;i=ed[i].nex)
40     {
41         if(!vis[ed[i].to]) dfs(ed[i].to,val^ed[i].w);
42         else insert(val^ed[i].w^vaa[ed[i].to]);
43 
44     }
45 }
46 LL query(LL x)
47 {
48     LL tmp=x;
49     for(re i=63;i>=0;i--)
50         if((tmp^lin[i])>tmp) tmp^=lin[i];
51     return tmp;
52 }
53 int main()
54 {
55 
56     ios::sync_with_stdio(false);
57 
58     cin>>n>>m;
59     for(re i=1;i<=m;i++)
60     {
61          int u,v;
62          LL val;
63         cin>>u>>v>>val;
64         add(u,v,val);
65 
66         add(v,u,val);
67 
68     }
69     dfs(1,0);
70     cout<<query(vaa[n]);
71     return 0;
72 }
View Code

 

      

posted on 2019-08-05 15:11  朔客  阅读(209)  评论(1)    收藏  举报