洛谷 P4151 [WC2011]最大XOR和路徑 解題報告
阿新 • • 發佈:2019-01-19
線性基 lse void add %d 回來 return for tdi
P4151 [WC2011]最大XOR和路徑
題意
求無向帶權圖的最大異或路徑
範圍
思路還是很厲害的,上午想了好一會兒都不知道怎麽做
先隨便求出一顆生成樹,然後每條返祖邊都可以出現一個環,從的路徑上走到環繞一圈再走回來去和回來的路徑抵消,於是對每個環加入線性基,詢問一下路徑在上面的最大值就行了
Code:
#include <cstdio> #define ll long long const int N=5e4+10; const int M=2e5+10; int head[N],to[M],Next[M],cnt; ll edge[M],base[65]; void add(int u,int v,ll w) { to[++cnt]=v,edge[cnt]=w,Next[cnt]=head[u],head[u]=cnt; } void ins(ll bee) { for(int i=62;~i;i--) if(bee>>i&1) { if(base[i]) bee^=base[i]; else {base[i]=bee;break;} } } ll qry(ll bee) { for(int i=62;~i;i--) if(!(bee>>i&1)) bee^=base[i]; return bee; } int vis[N],n,m;ll dis[N]; void dfs(int now,ll bee) { dis[now]=bee; vis[now]=1; for(int v,i=head[now];i;i=Next[i]) if(!vis[v=to[i]]) dfs(v,bee^edge[i]); else ins(dis[now]^dis[v]^edge[i]); } int main() { scanf("%d%d",&n,&m); ll w; for(int u,v,i=1;i<=m;i++) { scanf("%d%d%lld",&u,&v,&w); add(u,v,w),add(v,u,w); } dfs(1,0); printf("%lld\n",qry(dis[n])); return 0; }
2019.1.19
洛谷 P4151 [WC2011]最大XOR和路徑 解題報告