Bzoj2115 [Wc2011] Xor
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
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 }
本文为博主原创文章,转载请注明出处。