BZOJ2115: [Wc2011] Xor

首先用dfs找出所有的环的权值{s},然后随便找一条1到n的路径权值v

发现v和s中的元素可以组合成任何路径的权值,然后就是线性基了

注意dfs不用加fa,因为有重边的

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #define MAXN 50000
 7 #define MAXM 100000
 8 #define ll long long
 9 #define pb push_back
10 using namespace std;
11 int n,m;
12 vector<ll> vs;
13 int fst[MAXN],nxt[MAXM<<1],to[MAXM<<1],cnt;
14 ll vl[MAXM<<1];
15 ll v[MAXN];
16 int b[MAXN];
17 void ins(int x,int y,ll w){
18     nxt[++cnt]=fst[x],fst[x]=cnt,to[cnt]=y,vl[cnt]=w;
19     nxt[++cnt]=fst[y],fst[y]=cnt,to[cnt]=x,vl[cnt]=w;
20 }
21 void dfs(int x){
22     b[x]=1;
23     for(int e=fst[x];e;e=nxt[e]){
24         int y=to[e];ll w=vl[e];
25         if(b[y]){vs.pb(v[x]^v[y]^w);}
26         else{v[y]=v[x]^w;dfs(y);}
27     }
28 }
29 void init(){
30     scanf("%d%d",&n,&m);
31     int x,y;ll w;
32     for(int i=1;i<=m;i++){
33         scanf("%d%d%lld",&x,&y,&w);
34         ins(x,y,w);
35     }
36     dfs(1);
37     sort(vs.begin(),vs.end());
38     vs.erase(vs.begin());
39     vs.erase(unique(vs.begin(),vs.end()),vs.end());
40 }
41 ll a[65];
42 void solve(){
43     for(int i=0;i<vs.size();i++){
44         for(int j=62;j>=0;j--){
45             if(vs[i]>>j){
46                 if(a[j]){
47                     vs[i]^=a[j];
48                 }
49                 else{
50                     a[j]=vs[i];
51                     break;
52                 }
53             }
54         }
55     }
56     ll p=v[n];
57     for(int i=62;i>=0;i--){
58         if(p<(a[i]^p))p=a[i]^p;
59     }
60     printf("%lld\n",p);
61 }
62 int main()
63 {
64     init();
65     solve();
66     return 0;
67 }

 

posted @ 2018-01-16 23:42  white_hat_hacker  阅读(111)  评论(0编辑  收藏  举报