【思维题 状压dp】APC001F - XOR Tree

可能算是道中规中矩的套路题吧……

Time limit : 2sec / Memory limit : 256MB

Problem Statement

You are given a tree with N vertices. The vertices are numbered 0 through N−1, and the edges are numbered 1 through N−1. Edge i connects Vertex xi and yi, and has a value ai. You can perform the following operation any number of times:

  • Choose a simple path and a non-negative integer x, then for each edge e that belongs to the path, change ae by executing ae←ae⊕x (⊕ denotes XOR).

Your objective is to have ae=0 for all edges e. Find the minimum number of operations required to achieve it.

Constraints

  • 2≤N≤105
  • 0≤xi,yi≤N−1
  • 0≤ai≤15
  • The given graph is a tree.
  • All input values are integers.

题目大意

给定一个 $n$ 个节点的树,节点的标号为 $0\sim n-1$,边的标号为 $1\sim n-1$。每条边 $i$ 连接节点 $x_i$ 和 $y_i$,并且有一个权值 $a_i$。你可以进行如下的操作若干次。

  • 选择一条简单路径以及一个非负整数 $x$,然后对于每条属于这条路径的边,将它的权值异或上 $x$。

你的目标是让所有边的权值变成 $0$,同时,最小化操作的次数。


题目分析

我的初步想法是考虑对路径权值按位拆分。可能是受以前做过的一道序列一维问题的影响吧,就一直朝着这个思路想下去了……这个思路的关键在于没法处理不同位的路径的合并。

考虑设计一个守恒的部分量:将每个点记点权为相连所有路径边权的异或和。这么处理的好处在于对路径(u,v)进行一次操作之后,全图只有u,v的点权改变。对于点权相同的点对,最优操作当然是直接将它们消去;于是最后剩下的点权最多只有16种。注意到点权0是没有影响的,所以处理完点权之后,再对剩下的15种点权做一遍状压dp就可以了。

//CXR的快读板子怎么这么快

 1 #include<bits/stdc++.h>
 2 #define Tp template<typename Ty>
 3 #define Ts template<typename Ty,typename... Ar>
 4 #define Reg register
 5 #define RI Reg int
 6 #define Con const
 7 #define CI Con int&
 8 #define I inline
 9 #define W while
10 #define N 100000
11 #define P 15
12 #define INF 1e9
13 #define Gmin(x,y) (x>(y)&&(x=(y)))
14 const int maxn = 100035;
15 const int maxs = 1<<17;
16
17 int n,cnt,a[maxn],f[maxs],sta,ans;
18
19 class Class_FIO
20 {
21     private:
22         #define FS 100000
23         #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
24         #define pc(c) (putchar(c))
25         #define tn(x) (x<<3)+(x<<1)
26         #define D isdigit(c=tc())
27         int T;char c,*A,*B,FI[FS],S[FS];
28     public:
29         I Class_FIO() {A=B=FI;}
30         Tp I void read(Ty& x) {x=0;W(!D);W(x=tn(x)+(c&15),D);}
31         Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
32         Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
33 }F;
34 int dp(int x)
35 {
36     if (!x) return 0;
37     if (f[x]!=-1) return f[x];
38     int ret = 1e9;
39     for (int i=1; i<16; i++)
40         if (x&(1<<i)) for (int j=1; j<16; j++)
41             if ((x&(1<<j))&&i!=j)
42                 ret = std::min(ret, dp(x^(1<<i)^(1<<j)^(1<<(i^j)))+1+((x&(1<<(i^j)))?1:0));
43     f[x] = ret;
44     return ret;
45 }
46 int main()
47 {
48     F.read(n);
49     memset(f, -1, sizeof f);
50     for (int i=1; i<n; i++)
51     {
52         int x,y,z;
53         F.read(x), ++x, F.read(y), ++y, F.read(z);
54         a[x] ^= z, a[y] ^= z;
55     }
56     for (int i=1; i<=n; i++)
57         if (a[i]&&((sta>>a[i])&1)) sta ^= 1<<a[i], ++ans;
58         else if (a[i]) sta ^= 1<<a[i];
59     printf("%d\n",ans+dp(sta));
60     return 0;
61 }

END

原文地址:https://www.cnblogs.com/antiquality/p/10392368.html

时间: 2024-08-04 22:47:42

【思维题 状压dp】APC001F - XOR Tree的相关文章

P3694 邦邦的大合唱站队/签到题(状压dp)

P3694 邦邦的大合唱站队/签到题 题目背景 BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题. 题目描述 N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶像. 现在要求重新安排队列,使来自同一乐队的偶像连续的站在一起.重新安排的办法是,让若干偶像出列(剩下的偶像不动),然后让出列的偶像一个个归队到原来的空位,归队的位置任意. 请问最少让多少偶像出列? 输入输出格式 输入格式: 第一行2个整数N,M. 接下来N个行,每行一个整数a_i(1\le a_i

状压DP入门——铺砖块

题目描述 现有n*m的一块地板,需要用1*2的砖块去铺满,中间不能留有空隙.问这样方案有多少种 输入 输入n,m(1<=n, m<=11) 有多组输入数据,以m=n=0结束 输出 输出铺砖块的方案数 样例输入 1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0 样例输出 1 0 1 2 3 5 144 51205 我A的第一道状压DP题是导游,感觉就是背包~~ 此题不是很懂 此题状压DP,DP[i][sta]表示前i行填满对第i+1行的影响为状态sta时的方案总数 易知

POJ 2411 &amp;&amp; HDU 1400 Mondriaan&#39;s Dream (状压dp 经典题)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12341   Accepted: 7204 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

刷题总结——bzoj1725(状压dp)

题目: 题目描述 Farmer John 新买了一块长方形的牧场,这块牧场被划分成 N 行 M 列(1<=M<=12; 1<=N<=12),每一格都是一块正方形的土地. FJ 打算在牧场上的某几格土地里种上美味的草,供他的奶牛们享用.遗憾的是,有些土地相当的贫瘠,不能用来放牧.并且,奶牛们喜欢独占一块草地的感觉,于是 FJ 不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边.当然,FJ 还没有决定在哪些土地上种草. 作为一个好奇的农场主,FJ 想知道,如果不考虑草地的总块数,

刷题向》关于第一篇状压DP BZOJ1087 (EASY+)

这是本蒟蒻做的第一篇状压DP,有纪念意义. 这道题题目对状压DP十分友善,算是一道模板题. 分析题目,我们发现可以用0和1代表每一个格子的国王情况, 题目所说国王不能相邻放置,那么首先对于每一行是否合法的判断条件就出来了:就是对于情况X,如果X&(x<<1)==0,即为合法情况. 同理这样我们就可以得出每一行对于上一行是否合法的条件:(x&y)==0&&(x&(y<<1))==0&&(x&(y>>1))==

[luoguP3694] 邦邦的大合唱站队/签到题(状压DP)

传送门 来自kkk的题解: 70分做法:枚举每个学校顺序,暴力. 100分:状压dp.从队列头到尾DP, 状态:f[i]表示i状态下最小的出列(不一致)的个数. 比如f[1101]表示从头到位为1/3/4乐队的偶像的最小出列个数. f[i]=min(f[i\ xor\ 2^j]+num[j]-(sum[length][j]-sum[length-num[j]][j]));f[i]=min(f[i xor 2?j??]+num[j]−(sum[length][j]−sum[length−num[j

Orz_panda cup I题 (xdoj1117) 状压dp

Orz_panda cup I题 (xdoj1117)  状压dp 1117: Insert Orz Pandas 时间限制: 2 Sec  内存限制: 128 MB提交: 15  解决: 5[提交][状态][讨论版] 题目描述 Orz panda emotion is a famous emotion in XDU/ACM-ICPC QQ groups.Big Big Xi loves to create new Orz panda emotions.Now he has a matrix w

QDUOJ 来自xjy的签到题(bfs+状压dp)

来自xjy的签到题 Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1分钟可以移动到非'#'的相邻格子(与当前所在格子具有公共边).花园下面有m个隧道,每个隧道有一个出口和一个入口.当爱丽丝到达隧道的入口时,她可以选择(也可以不选择)进入隧道入口,并通过隧道一次,然后立即(不花费时间)出现在隧道出口.爱丽丝一开始可以降临在花园的任何地方.有好奇心的爱丽丝想知道,她通过所有

hdu 1185 状压dp 好题 (当前状态与上两行有关系)

/* 状压dp 刚开始&写成&&看了好长时间T0T. 状态转移方程 dp[i][k][j]=Max(dp[i][k][j],dp[i-1][l][k]+num[i][j]);(第i行的第j个状态有上一行的第k个状态得到) num[i][j]有两个功能,第一:判断第i行第j个状态是否合法 第二:判断第i行第j个状态的数目 */ #include<stdio.h> #include<string.h> #define N 110 int dp[N][N][N];