bzoj2155(高斯消元,线性基)
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
Sample Output
6
HINT
Source
就是很多个环和一个到n的路径中取个异或最大…
然后就是高斯消元的经典运用了.
也是线性基
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
bool IOerror = 0;
inline char nc(){
static char buf[BUF_SIZE],*p1 = buf+BUF_SIZE, *pend = buf+BUF_SIZE;
if(p1 == pend){
p1 = buf; pend = buf+fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1){ IOerror = 1; return -1;}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
inline ll rd(){
bool sign = 0; char ch = nc();ll x = 0;
for(; blank(ch); ch = nc());
if(IOerror)return 0;
if(ch == '-') sign = 1, ch = nc();
for(; ch >= '0' && ch <= '9'; ch = nc()) x = x*10+ch-'0';
if(sign) x = -x;
return x;
}
#undef OUT_SIZE
#undef BUF_SIZE
};
using namespace fastIO;
int n , m , t , linkk[50100] , num;
struct node{int n,y;ll v;}e[201000];
ll a[101000],v[101000],fk;
bool vis[101000];
void insert()
{
int x = rd(),y = rd();ll z = rd();
e[++t].y = y;e[t].n = linkk[x];e[t].v = z;linkk[x] = t;
e[++t].y = x;e[t].n = linkk[y];e[t].v = z;linkk[y] = t;
}
void dfs(int x,ll now,int fa)
{
v[x] = now;vis[x] = true;
if(x == n) fk = now;
rept(i,x)
if(e[i].y != fa)
if(!vis[e[i].y])
dfs(e[i].y,now^e[i].v,x);
else if(v[e[i].y]!=-1)a[++num] = v[x]^v[e[i].y]^e[i].v;
v[x] = -1;
}
void gus()
{
n = num;int M = n;
rep(i,1,n)
{
rep(j,i+1,n) if(a[j] > a[i]) swap(a[i],a[j]);
int k;
if(a[i] == 0) {M = i-1;break;}
for(k=60;k>=0;--k) if(a[i]>>k&1) break;
rep(j,1,n) if(i != j && (a[j]>>k&1)) a[j]^=a[i];
}
ll now = fk;
rep(i,1,M) if((now ^ a[i]) > now) now ^= a[i];
printf("%lld",now);
}
int main()
{
n = rd();m = rd();
rep(i,1,m) insert();
dfs(1,0,0);
gus();
return 0;
}