一棵樹,要遍歷所有的邊,不能往回走。走到盡頭的時候可以傳送到另乙個點,首先要保證使用傳送次數最少。
所走的路徑是最小鏈覆蓋,由兩個兩個葉子的鏈組成,如果有奇數個子葉節點,那麼會多一條從某乙個葉子到祖先的一條特殊路徑。
那麼對於每乙個葉節點,一定有且只有一條指向祖先的路徑。對於乙個非葉,會收到來自子節點上傳的多條路徑,那麼這時兩兩合併一定最優,但是又必須要保證它向根的路徑被覆蓋。所以如果上傳了奇數個路徑那麼正好把多餘的乙個繼續上傳,如果是偶數個路徑則要一次上傳兩個。如果共有偶數個葉節點,那麼在根上就會兩兩合併。如果是奇數個葉節點,就要考慮用多出的那條路徑來省去一些偶數上傳。
下面論證這一做法對於多出路徑為到根的正確性。如果不讓那條奇數路徑到根,那麼我們需要從另一方向引兩條路徑來填補這條奇數路徑來的方向,這正好是符合-1(即答案+1),而到了拐點,接下來搜尋的最大「長度」正好表示了用這條路徑改接所能達到的效果。請看圖。
注意!搜尋起點的根最好是非葉節點。
#include
#include
#include
using
namespace
std;
#define maxn 100005
vector
g[maxn];
bool eve[maxn];
int ans;
int dmax;
int dfs(int u, int fa)
}if(isleaf || cnt & 1)
return
1; eve[u] = true;
return2;}
void fd(int u, int fa, int d)
}int main()
ans = n - 1;
for(x=1; g[x].size()==1; x++);
cnt = dfs(x, 0);
if((cnt & 1) == 0)
dmax = 0;
fd(x, 0, 0);
printf("%d\n", ans - dmax);
}return
0;}
2016ACM多校 HDU5787 數字DP
求 l,r 中這樣一種數的個數,它的每連續k位都滿足兩兩不相同。2 k 5 k很小,典型的數字動態規劃,為了方便寫成記憶話搜尋的形式。從高位往低位決策,傳入之前臨近的k位是哪些數,這一位是否可以自由列舉0 9,是否來自前導零。為了修改最近的k位所占用的數,要用乙個佇列或者其他資料結構維護填數的先後順...
2016多校集訓 hdu5852
題目是乙個棋盤,給你k個棋子和k個目的地,每乙個棋子都是在1行,每乙個目的地都是在n行,要求找出讓k個棋子移動到k個目的地的路徑不交叉的方案數。這個其實也是個套路題目,知道乙個定理。就可以,但是我不知道定理的名字。但是考慮2個棋子的情況 a1 a2 b1 b2 其中使用a b表示 a到b的方案數 那...
2016多校聯賽 hdu 5724 Chess
此題就是乙個sg函式的題目,需要找出每一行的sg值,然後異或就可以咯。找sg需要在初始化的時候就找,也就是在t之前,暴力找出所有情況的sg。注意這個題只有20行,所以狀態壓縮一下就可以,每一行有棋子的地方就置為1,每一的地方就是0.include include include include in...