日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/21 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【思维题 状压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

總結

以上是生活随笔為你收集整理的【思维题 状压dp】APC001F - XOR Tree的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。