標籤:des style blog http io ar color os sp
| Description |
|
J國和C國爆發了戰爭,J國派出了很多間諜深入到C國內部,經常在C國的城市之間炸毀道路,阻攔C國的軍隊,C國為了抓到這些間諜,需要派人在城市進行監視,一個城市只要有一個人監視,那麼這個城市的所有的道路也都會被監視到,為了能夠盡量多計程車兵去前線打仗,監視計程車兵要儘可能的少,希望靠你編程求出至少需要多少人能實現對所有城市之間道路的監視。 |
| Input |
|
有多組測試資料
每組測試資料的第一行,一個整數n表示C國城市的數量(編號為0-----n-1) n<=2000
接下來n行:i:(M)表示有M個城市和城市i之間有道路連通,然後是M個整數表示和i連通的城市的編號。
處理到檔案結束,輸入資料保證是一棵樹。 |
| Output |
|
輸出一個整數,表示至少需要多少士兵能實現對所有道路的監視。 |
| Sample Input |
|
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0) |
| Sample Output |
| 1 |
| Source |
| Southeastern Europe 2000 |
分析:這個題跟上一個很像
dp[x][0]表示x為根節點的樹不選x點並且把所有的點都覆蓋的的最少士兵
dp[x][1]表示x為根節點的樹選x點並且把所有的點都覆蓋的的最少士兵
dp[x][0] = sum(dp[y][1]) + 1
dp[x][1] = sum(min(dp[y][0], dp[y][1]))
代碼:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 2005; 7 int dp[maxn][2]; 8 int n; 9 int in[maxn], out[maxn];10 struct Node {11 int to, next;12 }e[maxn * maxn];13 int tot;14 int head[maxn];15 void add(int u, int v) {16 e[tot].to = v;17 e[tot].next = head[u];18 head[u] = tot++;19 }20 int boss;21 22 void dfs(int u) {23 if(out[u] == 0) {24 dp[u][0] = 0;25 dp[u][1] = 1;26 return ;27 }28 int sum1 = 0; int sum2 = 0;29 for(int i = head[u]; i; i = e[i].next) {30 int v = e[i].to;31 dfs(v);32 sum1 += dp[v][1];33 sum2 += min(dp[v][0], dp[v][1]);34 }35 dp[u][0] = sum1;36 dp[u][1] = sum2 + 1;37 }38 39 int DP() {40 memset(dp, 0, sizeof(dp));41 dfs(boss);42 return min(dp[boss][0], dp[boss][1]);43 }44 45 int main() {46 int u, m, v;47 while(EOF != scanf("%d",&n) ) {48 memset(in, 0, sizeof(in));49 memset(out, 0, sizeof(out));50 memset(head, 0, sizeof(head));51 tot = 1;52 for(int i = 1; i <= n; i++) {53 scanf("%d:(%d)", &u, &m);54 for(int j = 1; j <= m; j++) {55 scanf("%d",&v);56 add(u, v);57 out[u]++; in[v]++;58 }59 }60 for(int i = 0; i < n; i++) {61 if(in[i] == 0) {62 boss = i;63 break;64 }65 }66 printf("%d\n", DP());67 }68 return 0;69 }View Code
HLG1477戰爭與守衛【樹形dp】