題目鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=2115
題目大意:中文題就不解釋題意了-,-
題目思路:由異或的性質我們可以知道,當我們從結點1出發走到一個環,再從這個環回到結點1,所得到的值正好是環上所有邊的權值異或和。因爲你走到一個環再回來,環上的邊只會被走過一次,這些值就能得到,而走到環的邊則會走兩次,這些值就會被抵消掉。這樣問題就可以轉化成了,從結點1開始直接走到結點n的邊權的異或和d[n],同時再走幾個環所能得到最大異或值。我們可以通過dfs先找出圖中的環,將環上邊的異或值存在一個數組a中,這樣就變成了從數組a中任取幾個數使得這幾個數與d[n]異或後得到的值最大,這就能用線性基來解決了。
具體實現看代碼:
#include <bits/stdc++.h>
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pb push_back
#define MP make_pair
#define lowbit(x) x&-x
#define clr(a) memset(a,0,sizeof(a))
#define _INF(a) memset(a,0x3f,sizeof(a))
#define FIN freopen("in.txt","r",stdin)
#define IOS ios::sync_with_stdio(false)
#define fuck(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
const int inf = 0x3f3f3f3f;
const int MX = 5e4 + 5;
struct LB {
ll d[61], p[61];
int cnt, mx;
LB() {
memset(d, 0, sizeof(d));
memset(p, 0, sizeof(p));
cnt = 0, mx = 61;
}
void init() {
memset(d, 0, sizeof(d));
memset(p, 0, sizeof(p));
}
bool add(ll val) {
/*插入時判斷之前是否有數會與val異或得0,判第k小時如果有爲0的情況,k要減一*/
for (int i = mx - 1; i >= 0; i--) {
if (val & (1LL << i)) {
if (!d[i]) {
d[i] = val; break;
}
val ^= d[i];
}
}
return val > 0;
}
bool query(ll val) { // 查詢val這個數是否存在
for (int i = mx - 1; i >= 0; i--) {
if (val & (1LL << i)) {
if (!d[i]) return 0;
val ^= d[i];
}
}
return 1;
}
ll query_max(ll val) {
ll ret = val;
for (int i = mx - 1; i >= 0; i--) if ((ret ^ d[i]) > ret) ret ^= d[i];
return ret;
}
ll query_min() {
for (int i = 0; i < mx; i++) if (d[i]) return d[i];
return 0;
}
void rebuild() {//消元,保存到p數組
cnt = 0;
for (int i = 0; i < mx; i++) {
for (int j = 0; j < i; j ++ )
if (d[i] & (1LL << j)) d[i] ^= d[j];
}
for (int i = 0; i < mx; i++) if (d[i]) p[cnt++] = d[i];
}
ll query_kth(ll k) { //使用前需要rebuild
ll ret = 0;
if (k >= (1LL << cnt)) return -1;
for (int i = cnt - 1; i >= 0; i--) if (k & (1LL << i)) ret ^= p[i];
return ret;
}
ll find(ll x) { //找x是第幾大的數,需保證x一定在
ll ret = 0, c = 0;
for (int i = 0; i < mx; i++) {
if (d[i]) {
if (x >> i & 1) ret += (1LL << c);
c++;
}
}
return ret;
}
LB operator+(const LB & _A)const { //合併
LB ret = *this;
for (int i = mx - 1; i >= 0; i--) if (_A.d[i]) ret.add(_A.d[i]);
return ret;
}
} base;
int n, m, cnt;
bool vis[MX];
ll d[MX], a[MX * 20];
vector<pll>E[MX];
void dfs(int u, int fa) {
vis[u] = 1;
for (int i = 0; i < (int)E[u].size(); i++) {
pll nw = E[u][i];
int v = nw.fi; ll w = nw.se;
if (v == fa) continue;
if (!vis[v]) {
d[v] = d[u] ^ w;
dfs(v, u);
} else a[cnt++] = d[u] ^ d[v] ^ w;
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v; ll w;
scanf("%d%d%lld", &u, &v, &w);
E[u].pb(MP(v, w));
E[v].pb(MP(u, w));
}
dfs(1, 0);
for (int i = 0; i < cnt; i++) base.add(a[i]);
ll ans = base.query_max(d[n]);
cout << ans << endl;
return 0;
}