【AtCoder3913】【Peterzavodsk Contest 001 F】XOR Tree(状压DP)
2018-03-24 16:28
399 查看
看了别人的题解,想了半天,我决定把它解释清楚一些。
当所有结点的VV值都为00时,边权也一定为00。
稍微证一下:假设所有VV值都为00了,边权仍有不为00的,则某个结点一定有至少两条不为00的边,则它的邻接点也至少有两条不为00的边,而这是一颗树,一定存在只有一条边的叶子结点,它不可能做到VV值为00,假设不成立。
将所有结点的VV值处理出来,先将每两个VV值相同的结点用一次操作处理为00(异或这个VV值),剩余单出来的使用二进制状压表示一个状态。
每次至少将一个VV值化为00为最优的转移。
稍微证一下:如果一次操作没有把任何一个VV化为00,如aa与bb同时异或ww,使得a⊕w=ca⊕w=c,b⊕w=db⊕w=d,以便于与另外存在的cc和dd进行异或同时处理,共33次操作; 也可以以每次操作消掉一个VV代替:①a⊕a=0a⊕a=0,c⊕a=wc⊕a=w;②b⊕b=0b⊕b=0,d⊕b=wd⊕b=w;③w⊕w=0w⊕w=0,w⊕w=0w⊕w=0。
每次枚举两个状态SS中的数i,ji,j,做一次他们异或的操作,使之变为0,i⊕j0,i⊕j,如果i⊕ji⊕j存在于状态S中,再用一次操作消除这它,即转移到一个新的状态。
题目大意
有N(2≤N≤105)N(2≤N≤105)个点的树,树边有权值a(0≤a≤15)a(0≤a≤15),每次操作可以把树上一条路径上所有边异或一个任意值ww,最少多少次操作可以使所有边权都变为00。题解
用V[u]V[u]表示把结点uu的所有边的权值异或和,那么选择一条路径u→vu→v全部异或ww只对端点V[u]V[u]和V[v]V[v]有影响(其它路径上的点分别被有两条边被异或,这些点的VV值被异或两次ww,VV值不变)。当所有结点的VV值都为00时,边权也一定为00。
稍微证一下:假设所有VV值都为00了,边权仍有不为00的,则某个结点一定有至少两条不为00的边,则它的邻接点也至少有两条不为00的边,而这是一颗树,一定存在只有一条边的叶子结点,它不可能做到VV值为00,假设不成立。
将所有结点的VV值处理出来,先将每两个VV值相同的结点用一次操作处理为00(异或这个VV值),剩余单出来的使用二进制状压表示一个状态。
每次至少将一个VV值化为00为最优的转移。
稍微证一下:如果一次操作没有把任何一个VV化为00,如aa与bb同时异或ww,使得a⊕w=ca⊕w=c,b⊕w=db⊕w=d,以便于与另外存在的cc和dd进行异或同时处理,共33次操作; 也可以以每次操作消掉一个VV代替:①a⊕a=0a⊕a=0,c⊕a=wc⊕a=w;②b⊕b=0b⊕b=0,d⊕b=wd⊕b=w;③w⊕w=0w⊕w=0,w⊕w=0w⊕w=0。
每次枚举两个状态SS中的数i,ji,j,做一次他们异或的操作,使之变为0,i⊕j0,i⊕j,如果i⊕ji⊕j存在于状态S中,再用一次操作消除这它,即转移到一个新的状态。
代码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=100005; int dp[1<<16],V[MAXN],cnt[16]; int DP(int s) { if(s==0) return 0; if(dp[s]!=-1) return dp[s]; dp[s]=0x3FFFFFFF; for(int i=1;i<16;i++) if(s&(1<<i)) for(int j=1;j<16;j++) if(s&(1<<j)) { int ns=s^(1<<i)^(1<<j)^(1<<(i^j)); if(__builtin_popcount(ns)<__builtin_popcount(s)) dp[s]=min(dp[s],DP(ns)+1+(((1<<(i^j))&s)==(1<<(i^j)))); } return dp[s]; } int main() { int n; scanf("%d",&n); for(int i=1,x,y,a;i<n;i++) { scanf("%d%d%d",&x,&y,&a); V[x]^=a; V[y]^=a; } for(int i=0;i<n;i++) if(V[i]) cnt[V[i]]++; int ans=0,st=0; for(int i=0;i<16;i++) { ans+=cnt[i]/2; st^=(cnt[i]&1)<<i; } memset(dp,-1,sizeof dp); ans+=DP(st); printf("%d\n",ans); return 0; }
相关文章推荐
- 【树形DP】[AtCoder Petrozavodsk Contest 001 E] Antennas on Tree
- 【AtCoder3910】【Peterzavodsk Contest 001 C】Vacant Seat(二分)
- AtCoder Peterzavodsk Contest 001 题解
- AtCoder Grand Contest 001 E - BBQ Hard 数学+dp
- AtCoder Grand Contest 017 F - Zigzag 状压dp
- AtCoder Regular Contest 073 F - Many Moves 线段树优化dp
- (dp)AtCoder Grand Contest 019 D - Shift and Flip
- AtCoder Grand Contest 012 B - Splatter Painting(dp)
- AtCoder Grand Contest 019 C - Fountain Walk 贪心+dp
- AtCoder Petrozavodsk Contest 001 简要题解
- AtCoder Grand Contest 001 E BBQ Hard
- AtCoder Petrozavodsk Contest 001 C - Vacant Seat 交互题、带分类讨论的二分
- AtCoder Grand Contest 001 F permutation
- AtCoder Grand Contest 001 B - Mysterious Light
- (dp)AtCoder Regular Contest 081 E - Don't Be a Subsequence
- AtCoder Grand Contest 017 D - Game on Tree
- AtCoder Grand Contest 001 C - Shorten Diameter
- Atcoder Grand Contest 016 D XOR Replace
- AtCoder Regular Contest 093(E-Bichrome Spanning Tree)
- AtCoder Grand Contest 015 E - Mr.Aoki Incubator dp