【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 }
浙公网安备 33010602011771号