題目描述
題目解析
首先如果直接思考那麼我們不容易得到答案,那麼我們換一種思路,我們先解決這個問題的弱化版本,我們考慮在無向圖
那麼我哦們可以容易的發現我們需要的就是包含
那麼我們整個問題就變成了兩個問題的合集
1. 給你N個數求取出一些數的異或和最大值
2. 判斷當前環路的異或值
那麼我們看這一題:http://blog.csdn.net/jeremygjy/article/details/50613026 我們用方法1,2都可以解決(推薦用2)或者還有第三種,詳見莫濤的PPT
對於每一個環我們發現如果每一次連接一條邊,那麼就會構成一個新的環,如果環中本來還有環路,那麼另一部分環路可以通過異或得到,所以不用考慮另一部分。貪心的獲得較高爲爲1之後我們看當前
代碼
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int MAXN = 50000;
const int MAXM = 200000;
struct node{
int v;
ll val;
node *next;
}Eds[MAXM*2+10], *ecnt=Eds, *adj[MAXN+10];
void addedge(int u, int v, ll t){
++ecnt;
ecnt->v = v;
ecnt->next = adj[u];
ecnt->val = t;
adj[u] = ecnt;
}
bool vis[MAXN+10];
ll sum[MAXN+10], As[MAXM+10];
void dfs(int u){
vis[u] = 1;
for(node *p=adj[u];p;p=p->next){
if(vis[p->v]){
As[++As[0]] = sum[p->v] ^ sum[u] ^ p->val;
continue;
}
sum[p->v] = sum[u] ^ p->val;
dfs(p->v);
}
}
void gauss_jordan(){
int i,row,col=59;
ll Max = 0;
for(int i=1;i<=As[0];i++)
Max = max(Max, As[i]);
for(row=1;row<=As[0]&&col>=0;row++,col--){
if(!(As[row]>>col)&1)
for(i=row+1;i<=As[0];i++)
if((As[i]>>col)&1){
swap(As[i],As[row]);
break;
}
if(!((As[row]>>col)&1)){
row--;
continue;
}
for(i=1;i<=As[0];i++)
if(i!=row&&(As[i]>>col)&1)
As[i]^=As[row];
}
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
int u, v;
long long val;
for(int i=1;i<=m;i++){
scanf("%d%d%lld", &u, &v, &val);
addedge(u, v, val);
addedge(v, u, val);
}
dfs(1);
gauss_jordan();
ll ans = sum[n];
for(int i=1;i<=As[0];i++)
ans = max(ans^As[i], ans);
printf("%lld\n", ans);
return 0;
}