An enemy with n Units will be wiped out when it is attacked and directly adjacent to an enemy. The minimum number of attacks required to destroy all enemies.
Duplicate coverage issues. I posted this question to describe whether it is necessary to optimize pruning. A small detail can determine whether it is TLE or AC.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cmath>
Using namespace std;
Const int maxn = 60*60 + 10;
Const int oo = 1 <30;
Const int maxrow = 60;
Const int maxcol = 60;
Int CTX [maxrow] [maxcol];
Int n, m, ans;
Int totRow, totCol, head, idx;
Int L [maxn], R [maxn], U [maxn], D [maxn];
Int RH [maxn], CH [maxn], S [maxn];
Void initctx ()
{
Memset (CTX, 0, sizeof (CTX ));
For (int I = 0; I <n; ++ I ){
CTX [I] [I] = 1;
}
Int a, B;
For (int I = 0; I <m; ++ I ){
Scanf ("% d", & a, & B );
A --; B --;
CTX [a] [B] = CTX [B] [a] = 1;
}
}
Int newNode (int up, int down, int left, int right)
{
U [idx] = up; D [idx] = down;
L [idx] = left; R [idx] = right;
U [down] = D [up] = L [right] = R [left] = idx;
Return idx ++;
}
Void build ()
{
Idx = maxn-1;
Head = newNode (idx, idx );
Idx = 0;
For (int j = 0; j <totCol; ++ j ){
NewNode (idx, idx, L [head], head );
CH [j] = j; S [j] = 0;
}
For (int I = 0; I <totRow; ++ I ){
Int k =-1;
For (int j = 0; j <totCol; ++ j ){
If (! CTX [I] [j]) continue;
If (-1 = k ){
K = newNode (U [CH [j], CH [j], idx, idx );
RH [k] = I; CH [k] = j; S [j] ++;
} Else {
K = newNode (U [CH [j], CH [j], k, R [k]);
RH [k] = I; CH [k] = j; S [j] ++;
}
}
}
}
Void remove (int c)
{
For (int I = D [c]; I! = C; I = D [I]) {
L [R [I] = L [I]; R [L [I] = R [I];/* S [CH [I] --; */
}
}
Void resume (int c)
{
For (int I = U [c]; I! = C; I = U [I]) {
L [R [I] = R [L [I] = I;/* S [CH [I] ++ ;*/
}
}
/* Valuation function */
Int h ()
{
Bool vis [maxcol];
Memset (vis, false, sizeof (vis ));
Int ret = 0;
For (int I = R [head]; I! = Head; I = R [I]) {
If (! Vis [I]) {
Ret ++;
Vis [I] = true;
For (int j = D [I]; j! = I; j = D [j]) {
For (int k = R [j]; k! = J; k = R [k]) {
Vis [CH [k] = true;
}
}
}
}
Return ret;
}
Void dance (int cnt)
{
If (cnt + h ()> = ans) {// enter ">"
Return;
}
If (R [head] = head ){
Ans = cnt;
Return;
}
Int c, Min = oo;
For (int I = R [head]; I! = Head; I = R [I]) {
If (S [I] <Min ){
Min = S [I]; c = I;
}
}
For (int I = D [c]; I! = C; I = D [I]) {
Remove (I );
For (int j = R [I]; j! = I; j = R [j]) {
Remove (j );
}
Dance (cnt + 1 );
For (int j = L [I]; j! = I; j = L [j]) {
Resume (j );
}
Resume (I );
}
Return;
} Www.2cto.com
Int main ()
{
While (scanf ("% d", & n, & m )! = EOF ){
TotRow = n; totCol = n;
Initctx ();
Build ();
Ans = oo;
Dance (0 );
Printf ("% d \ n", ans );
}
Return 0;
}