您的位置:首页 > 其它

BZOJ 2115: [Wc2011] Xor

2016-10-15 11:09 239 查看
贪心求线性基+找环

挂题解:http://www.cnblogs.com/BLADEVIL/p/3484486.html

任何复杂环一定能由简单环异或得到

任何一条1~n的路径的异或值都可以通过其他的1~n的路径异或一些环得到

然后求出所有环,搞出线性基,贪心一下即可

简单环的个数一定是m-n+1

#include<cstdio>
#include<algorithm>
#define N 50005
#define M 100005
#define reg register
#define ll long long
using namespace std;
struct edge{int next,to;ll val;}e[M<<1];
int ecnt = 1, last
, cnt, dep
;
ll a[M], f
;
void addedge(int a, int b ,ll c)
{
e[++ecnt]=(edge){last[a],b,c};
last[a]=ecnt;
}
void dfs(int x, ll sum, int from)
{
dep[x]=dep[e[from].to]+1;
f[x]=sum;
for(int i = last[x]; i; i=e[i].next)
{
int y=e[i].to;
if(i==from)continue;
if(dep[y] && dep[y]<=dep[x])
{
a[++cnt]=f[x]^f[y]^e[i].val;
}
else if(!dep[y])
{
dfs(y,sum^e[i].val,i^1);
}
}
}
int main()
{
int n, m;
ll ans=0;
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
{
int a, b; ll c;
scanf("%d%d%lld",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
dfs(1,0,0);
ans=f
;
int tot=0;
for(ll pos = 1ll<<59; pos; pos>>=1)
{
int i;
for(i = tot+1; i <= cnt; i++)
if(a[i]&pos)
{
++tot;
swap(a[tot],a[i]);
break;
}
if(i<=cnt)
{
if((ans&pos)==0)ans^=a[tot];
for(int j = tot+1; j <= cnt; j++)
if(a[j]&pos)
a[j]^=a[tot];
}
}
printf("%lld\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: