1. 程式人生 > >bzoj2115: [Wc2011] Xor

bzoj2115: [Wc2011] Xor

main 線性 fin con continue add max wc2011 www.

題目鏈接

bzoj2115: [Wc2011] Xor

題解

問題有環,首先我們不考慮率環,得到一條最優路徑
那麽,我們只需要要把在線性基上貪心的取環的貢獻就好了,顯然,我們沿著路徑來回得到環的異或價值
我們可以任意的取一個到n的路徑然後對於所有環構成的線性基貪心
這為什麽是對的呢,任意取得如果不優呢
如果不優的話,選取的這臺路徑與最優路徑是構成環的,那麽異或之後首先搜出的路徑價值就沒了

代碼

#include<cstdio> 
#include<algorithm> 
#define LL long long 
inline LL read() { 
    LL x = 0
;//,f = 1; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); return x ;//* f; } #define int long long const int maxn = 1000007; int n,m; int head[maxn],num = 0
; struct Edge { int v,next;LL w; } edge[maxn << 1]; inline void add_edge(int u,int v,LL w) { edge[++ num].v = v;edge[num].w = w;edge[num].next = head[u];head[u] = num; } LL dis[maxn]; LL b[90]; void insert(LL x) { for(LL i = 62;i >= 0;-- i) if((x >> i) & 1
) { if(!b[i]) {b[i] = x;return;} x = x ^ b[i]; } } bool vis[maxn]; void dfs(int x,int fa) { vis[x] = true; for(int i = head[x];i;i = edge[i].next) { int v = edge[i].v; if(v == fa)continue; if(vis[v]) {insert(dis[x] ^ dis[v] ^ edge[i].w);continue;} dis[v] = dis[x] ^ edge[i].w; dfs(v,x); } } main() { n = read(),m = read(); for(int u,v,i = 1;i <= m;++ i) { u = read() ,v = read();LL w = read(); add_edge(u,v,w);add_edge(v,u,w); } dfs(1,0); LL ans = dis[n]; for(int i = 62;i >= 0;i --) if((ans ^ b[i]) > ans) ans ^= b[i]; printf("%lld\n",ans); return 0; }

bzoj2115: [Wc2011] Xor