(线性基) bzoj 2115
2115: [Wc2011] Xor
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1258 Solved: 550
[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
求异或最长路啊,
首先随便找一条路,然后找环啊,判断环,用线性基啊
#include<iostream> #include<cstdio> #include<cstring> #include<cstdio> #include<cmath> #include<string> #include<algorithm> #include<queue> #include<vector> #include<set> #include<stack> #include<map> using namespace std; long long n,m,cnt; vector<long long> w[250005]; vector<long long> e[250005]; bool vis[250005]; long long a[250005],ins[66],d[250005]; void dfs(int x) { vis[x]=1; for(int i=0;i<e[x].size();i++) { int v=e[x][i]; if(!vis[v]) d[v]=d[x]^w[x][i],dfs(v); else a[++cnt]=d[v]^w[x][i]^d[x]; } } void solve() { for(int i=1;i<=cnt;i++) { for(int j=63;j>=0;j--) { if((a[i]>>j)&1) { if(!ins[j]) { ins[j]=a[i]; break; } else a[i]^=ins[j]; } } } long long ans=d[n]; for(int i=63;i>=0;i--) if((ans^ins[i])>ans) ans=(ans^ins[i]); printf("%lld\n",ans); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { long long x,y,z; scanf("%lld%lld%lld",&x,&y,&z); e[x].push_back(y); e[y].push_back(x); w[x].push_back(z); w[y].push_back(z); } dfs(1); solve(); return 0; }