【問題描述】
【輸入格式】
測試資料表示一棵樹,描述如下:
第一行 n,表示樹中結點的數目。
第二行至第n+1行,每行描述每個結點資訊,依次為:該結點標號i,k(後面有k條邊與結點i相連)。接下來k個數,分別是每條邊的另乙個結點標號r1,r2,...,rk。
對於乙個n(0【輸出格式】
輸出檔案僅包含乙個數,為所求的最少的士兵數目。
例如,對於如下圖所示的樹:
2 3
答案為1(只要乙個士兵在結點1上)。
【輸入樣例1】
0 1 1
1 2 2 3
2 03 0
【輸出樣例1】
【輸入樣例2】
3 3 1 4 2
1 1 0
2 00 0
4 0【輸出樣例2】
【解析】
這道題和上一道【皇宮看守(guard)】有相似之處..但是這道題的狀態定義與上一題有少許不同..
上一道題需要點安全,但這一道題是需要邊安全 = =
這是個值得困擾的問題.. 你要邊安全但是又只能搜尋點0.0
那麼我們就可以這樣定義每乙個點所代表的
比如說點i,我們就可以說點i是否有人,點i所連線的邊(以i為根的樹,同下)是否安全。這樣來做乙個狀態,我們又可以像上一題那樣分出4種狀態。
f[i][0] 表示點i沒人所連線的邊安全的最小花費
f[i][1] 表示點i沒人所連線的邊不安全的最小花費
f[i][2] 表示點i有人所連線的邊安全的最小花費
f[i][3] 表示點i有人所連線的邊不安全的最小花費 #既然有人怎麼會不安全呢.. 所以這種狀態可以不管0.0
這個時候問題也就來了..沒人不安全這個狀態有沒有用呢..
1——0——0——1(根)
這樣子四個點都是安全的。
但現在需要的是邊安全,那麼在同樣情況下:
1——0——0——1(根)
這是不安全的,因為紅色的邊這一條邊是不安全的,而藍色這乙個點的狀態正是沒人不安全..
以上證明:沒人不安全這個狀態是沒有用的!
那麼同樣的道理,沒人安全這種狀態就需要孩子節點全都是有人安全的!
那這道題就輕易解決啦!
【核心**】
void tree_dp ( int x )
f[x][0] = f0;
f[x][1] = f1;
}
【完整**】
#include #include #include using namespace std;
struct node a[2100]; int first[2100], len, n;
void ins ( int x, int y )
int f[2100][2];
int _min ( int x, int y )
void tree_dp ( int x )
f[x][0] = f0;
f[x][1] = f1;
}bool v[2100];
int main ()
} int st;
for ( i = 0; i < n; i ++ )
} tree_dp (st);
printf ( "%d\n", _min ( f[st][0], f[st][1] ) );
return 0;
}
樹形DP 戰略遊戲
鮑勃喜歡玩電腦遊戲,特別是戰略遊戲,但有時他找不到解決問題的方法,這讓他很傷心。現在他有以下問題。他必須保護一座中世紀城市,這條城市的道路構成了一棵樹。每個節點上的士兵可以觀察到所有和這個點相連的邊。他必須在節點上放置最少數量的士兵,以便他們可以觀察到所有的邊。你能幫助他嗎?例如,下面的樹 只需要放...
樹形DP 戰略遊戲
description input 輸入檔案中資料表示一棵樹,描述如下 第一行 n,表示樹中結點的數目。第二行至第n 1行,每行描述每個結點資訊,依次為 該結點標號i,k 後面有k條邊與結點i相連 接下來k個數,分別是每條邊的另乙個結點標號r1,r2,rk。對於乙個n 0 n 1500 個結點的樹,...
戰略遊戲 樹形DP入門)
題目鏈結 here 題目分析 放置哨兵無非兩種情況,放或不放,我們可以用dp i 1 來表示第i個結點放置哨兵,dp i 0 來表示第i個結點不放置哨兵,我們可以從上往下,從左往右來遍歷樹,所以這就用到了樹形dp的知識,我們很容易知道,如果父親結點沒放哨兵,那麼子結點肯定要放置哨兵,如果父親放置了哨...