首页 > 代码库 > BZOJ2115 WC2011 XOR

BZOJ2115 WC2011 XOR

技术分享

一开始的时候被吓傻了

但一条边异或两次就毫无意义了

所以跑出来的结果是一条路径加若干环

判环用高斯消元就好了

最后把每个环与直接跑路径的结果做比较就好了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=200010;
 5 vector<pair<int,ll> > G[N];
 6 bool vis[N];
 7 int cir,tot,cnt,n;
 8 ll d[N],V[N];
 9 void dfs(int u){
10     vis[u]=1;
11     for(int i=0,i_end=G[u].size();i<i_end;++i){
12         int v=G[u][i].first;
13         ll w=G[u][i].second;
14         if(!vis[v])d[v]=d[u]^w,dfs(v);
15         else V[++cir]=d[u]^d[v]^w;
16     }
17 }
18 void Gauss(){
19     for(ll i=1ll<<60;i;i>>=1){
20         
21         int j=tot+1;
22         while(j<=cir&&!(V[j]&i))j++;
23         if(j==cir+1)continue;
24         
25         tot++;swap(V[tot],V[j]);
26         
27         for(int k=1;k<=cir;k++)
28             if(k!=tot&&(V[k]&i))
29                 V[k]^=V[tot];
30     }
31 }
32 int main(){
33     int m;
34     scanf("%d%d",&n,&m);
35     while(m--){
36         int u,v;ll w;
37         scanf("%d%d%lld",&u,&v,&w);
38         G[u].push_back(make_pair(v,w));
39         G[v].push_back(make_pair(u,w));
40     }
41     dfs(1);Gauss();
42     ll ans=d[n];
43     for(int i=1;i<=tot;++i)
44         ans=max(ans,ans^V[i]);
45     printf("%lld\n",ans);
46     return 0;
47 }

不算太麻烦,只是一开始写高斯消元写挂了

还是要多多练习

BZOJ2115 WC2011 XOR