码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2115 [Wc2011] Xor

时间:2015-02-14 23:43:54      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

开始补冬令营期间做的题目啦~

好吧冬令营ydl大爷在上面讲图的树分解,我们一帮二子在下面讨论这道题,讨论了2个小时2333

进入正题。。。首先我们把图dfs一遍,记录下这颗dfs的生成树

我们会发现,所有边分成了两种:树边和回边,并且不存在两棵子树之间有边。

定义回边和其中的树边形成的环叫基本环,则基本环最多有m - n个

然后题解上有一句话"不难发现,答案是由1到n号点的一条树链和几个基本环形成的",我去脑补半天啊!!!因为是xor所以来回路径上的边都算了两次刚好抵消掉。

于是题解君就卖了个萌"高斯消元即可"。。。什么鬼。。。

(未完待续)

 

技术分享
 1 /**************************************************************
 2     Problem: 2115
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:328 ms
 7     Memory:11412 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12  
13 using namespace std;
14 typedef long long ll;
15 const int N = 50005;
16 const int M = N << 2;
17 const int Cnt = 100;
18 const int Maxlen = M * 30;
19  
20 struct edge {
21     int next, to;
22     ll v;
23     edge() {}
24     edge(int _n, int _t, ll _v) : next(_n), to(_t), v(_v) {}
25 } e[M];
26  
27 int n, m, cnt;
28 int first[N];
29 ll f[N], Ans;
30 ll ans[Cnt], from[Cnt];
31 bool vis[N];
32  
33 char buf[Maxlen], *c = buf;
34 int Len;
35  
36 inline ll read() {
37     ll x = 0;
38     while (*c < 0 || 9 < *c) ++c;
39     while (0 <= *c && *c <= 9)
40         x = x * 10 + *c - 0, ++c;
41     return x;
42 }
43  
44 #define y e[x].to
45 void dfs(int p) {
46     int x;
47     vis[p] = 1;
48     for (x = first[p]; x; x = e[x].next)
49         if (!vis[y]) {
50             f[y] = f[p] ^ e[x].v;
51             dfs(y);
52         }
53 }
54 #undef y
55  
56 void work(int x, int y, ll v) {
57     int i;
58     v = v ^ f[x] ^ f[y];
59     for (i = 1; i <= cnt && v; ++i)
60         if (v & ans[i]) v ^= from[i];
61     if (!v) return;
62     ++cnt, ans[cnt] = 1, from[cnt] = v;
63     while ((ans[cnt] << 1) <= v) ans[cnt] <<= 1;
64     for (i = cnt; i > 1; --i)
65         if (ans[i] > ans[i - 1])
66             swap(ans[i], ans[i - 1]), swap(from[i], from[i - 1]);
67 }
68  
69 int main() {
70     Len = fread(c, 1, Maxlen, stdin);
71     buf[Len] = \0;
72     int i, x, y;
73     ll z;
74     n = read(), m = read();
75     for (i = 1; i <= m; ++i) {
76         x = read(), y = read(), z = read();
77         e[i] = edge(first[x], y, z), first[x] = i;
78         e[i + m] = edge(first[y], x, z), first[y] = i + m;
79     }
80     dfs(1);
81     for (i = 1; i <= m; ++i)
82         work(e[i].to, e[i + m].to, e[i].v);
83     Ans = f[n];
84     for (i = 1; i <= cnt; ++i)
85         if (!(Ans & ans[i])) Ans ^= from[i];
86     printf("%lld\n", Ans);
87     return 0;
88 }
View Code

 

BZOJ2115 [Wc2011] Xor

标签:

原文地址:http://www.cnblogs.com/rausen/p/4292257.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!