2016ACM多校 HDU5758 貪心 搜尋

2021-07-15 17:44:38 字數 1181 閱讀 2493

一棵樹,要遍歷所有的邊,不能往回走。走到盡頭的時候可以傳送到另乙個點,首先要保證使用傳送次數最少。
所走的路徑是最小鏈覆蓋,由兩個兩個葉子的鏈組成,如果有奇數個子葉節點,那麼會多一條從某乙個葉子到祖先的一條特殊路徑。

那麼對於每乙個葉節點,一定有且只有一條指向祖先的路徑。對於乙個非葉,會收到來自子節點上傳的多條路徑,那麼這時兩兩合併一定最優,但是又必須要保證它向根的路徑被覆蓋。所以如果上傳了奇數個路徑那麼正好把多餘的乙個繼續上傳,如果是偶數個路徑則要一次上傳兩個。如果共有偶數個葉節點,那麼在根上就會兩兩合併。如果是奇數個葉節點,就要考慮用多出的那條路徑來省去一些偶數上傳。

下面論證這一做法對於多出路徑為到根的正確性。如果不讓那條奇數路徑到根,那麼我們需要從另一方向引兩條路徑來填補這條奇數路徑來的方向,這正好是符合-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...