【BZOJ2115】【Wc2011】 Xor 线性基 异或最长路

#include <stdio.h>
int main()
{
	puts("转载请注明出处谢谢");
	puts("http://blog.csdn.net/vmurder/article/details/43410545");
}


题意:找一条异或最长路。

题解:先随便来一条路径,然后我们发现这条路径上可以随便加简单环(不管有没有共点共边)、


就是因为可以先从某点走到环上来一圈再走回来,这样来去的路径被搞没了,简直污得不行。

然后我们可以用线性基来决定去异或哪些环。


并没有错。


算了来点干的吧,上面的都是在扯淡。

SARFT Warning:

5>>64=?

5>>65=?


我来告诉你! 分别是5和2!

那个英文是广电总局的意思。


所以大家注意线性基就安心扫到63得了,不要像我一样作死循环到65。

WA了好久啊!!!!!


代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 50100
#define M 101000
using namespace std;
struct KSD
{
	int v,next;
	long long len;
}e[M<<1];
int head[N],cnt;
inline void add(int u,int v,long long len)
{
	e[++cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int n,m;
bool vis[N];
long long d[N],a[M];
long long ins[70];
void dfs(int x)
{
	vis[x]=true;
	int i,v;
	for(i=head[x];i;i=e[i].next)
	{
		v=e[i].v;
		if(!vis[v])d[v]=d[x]^e[i].len,dfs(v);
		else a[++m]=d[v]^e[i].len^d[x];
	}
}
void Ins()
{
	int i,j;
	for(i=1;i<=m;i++)
	{
		for(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(i=63;i>=0;i--)
		if((ans^ins[i])>ans)
			ans^=ins[i];
	printf("%lld\n",ans);
}
int main()
{
	freopen("test.in","r",stdin);

	int i,j;
	long long len;
	scanf("%d%d",&n,&m);
	while(m--)
	{
		scanf("%d%d%lld",&i,&j,&len);
		add(i,j,len),add(j,i,len);
	}
	dfs(1);
	Ins();
	return 0;
}



你可能感兴趣的:(XOR,最长路,BZOJ2115,线性基,Wc2011)