Bzoj2115 [Wc2011] Xor

 

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 2858  Solved: 1209
[Submit][Status][Discuss]

Description

Input

第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。

Output

仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。

Sample Input

5 7
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2

Sample Output

6

HINT

 

 

DFS  线性基

一条路径走两遍,权值就被异或没了。

最终结果可以看作从1到n的路径的权值,异或数量不等的环的权值。

DFS出所有简单环的权值,作为基底,动态维护线性基,找出最大的异或结果

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #define LL long long
 7 using namespace std;
 8 const int mxn=50010;
 9 int read(){
10     int x=0,f=1;char ch=getchar();
11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 LL read1(){
16     LL x=0,f=1;char ch=getchar();
17     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
18     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 struct edge{
22     int v,nxt;
23     LL dis;
24 }e[mxn<<2];
25 int hd[mxn],mct=0;
26 void add_edge(int u,int v,LL w){
27     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].dis=w;hd[u]=mct;return;
28 }
29 int n,m;
30 LL a[mxn<<3],p[mxn];
31 int cnt=0;
32 LL dis[mxn<<3];bool vis[mxn];
33 void DFS(int u){
34     vis[u]=1;
35     for(int i=hd[u];i;i=e[i].nxt){
36         int v=e[i].v;
37         if(!vis[v]){
38             dis[v]=dis[u]^e[i].dis;
39             DFS(v);
40         }
41         else a[++cnt]=dis[u]^dis[v]^e[i].dis;
42     }
43     return;
44 }
45 void solve(){
46     int i,j;
47     for(i=1;i<=cnt;i++){
48         for(j=63;j>=0;j--){
49             if(!((a[i]>>j)&1))continue;
50             if(!p[j]){p[j]=a[i];break;}
51             a[i]^=p[j];
52         }
53     }
54     return;
55 }
56 int main(){
57     n=read();m=read();
58     int i,j;
59     int u,v;LL w;
60     for(i=1;i<=m;i++){
61         u=read();v=read();w=read1();
62         add_edge(u,v,w);
63         add_edge(v,u,w);
64     }
65     DFS(1);
66     solve();
67     LL ans=dis[n];
68     for(i=63;i>=0;i--){
69         ans=max(ans,ans^p[i]);
70     }
71     printf("%lld\n",ans);
72     return 0;
73 }

 

posted @ 2017-01-27 18:08  SilverNebula  阅读(185)  评论(0编辑  收藏  举报
AmazingCounters.com