http://codeforces.com/contest/845/problem/G
只能说太强了。
给定一个图,距离为边的异或值。问你异或值最小。
想象如果有多条不想交的路可以从1到达m。
我们可以先计算其中一条路线的异或值,在计算他们的异或前缀和。
然后这些和分别异或 第一条路,和第一条一起 取最小值。
#include<cstring>
#include<cstdio>
#include <bits/stdc++.h>
using namespace std;
/* 不知道咋说这一道题,
vt保存的是 1到i的边权的抑或值。
dis是 1到i的另一个值(在环上的)。
loop里面存的是包含当前环之间异或的最小值
*/
const int maxn=1e5+3000;
vector<int>v;
vector<pair<int,int> >G[maxn];
int vt[maxn];
bool vis[maxn];
void add(int x){
for(int i=0;i<v.size();i++)
x=min(x,x^v[i]);
if(x) v.push_back(x);//当前过环的最小值。
}
void dfs(int u,int len){
vis[u]=true;
vt[u]=len;
for(int i=0;i<G[u].size();i++){
int to=G[u][i].first;
int dd=G[u][i].second;
if(vis[to])
add(len^vt[to]^dd);
else
dfs(to,len^dd);
}
}
int main(){
int t,m,n,a,b,c;
scanf("%d%d",&m,&n);
for(int i=0;i<maxn;i++)
G[i].clear();
for(int i=0;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
G[a].push_back(make_pair(b,c));
G[b].push_back(make_pair(a,c));
}
dfs(1,0);
for(int i=0;i<v.size();i++){
vt[m]=min(vt[m],vt[m]^v[i]);
}
printf("%d\n",vt[m]);
return 0;
}