中山市石一個環境優美、氣候宜人的小城市。因爲城市的交通並不繁忙,市內的道路網很稀疏。準確地說,中山市有N-1條馬路和N個路口,每條馬路連接兩個路口,每兩個路口之間最多隻有一條馬路。作爲一條交通網絡,顯然每兩個路口之間都是可達的。爲了更好地管理中山市的交通,市長決定在一些路口加裝電子眼,用來隨時監視路面情況。這些裝在路口的電子眼能夠監視所有連接到這個路口的馬路。現在市長想知道最少需要在多少個路口安裝電子眼才能監視所有的馬路。市長已經把所有的路口都編上了1~N的號碼。
給你中山市的地圖,你能幫忙嗎?
輸入文件traffic.in的第1行包括一個數字N(1<=N<=100000),表示中山市的路口數。接下來N-1行,每行兩個數字x_i和y_i,用來描述N-1條路所連接的兩個路口的編號。
輸出最少需要安裝電子眼的數量。
3
1 2
1 3
1
其實和沒有上司的晚會基本一致,就把求最大改成求最小就好了。。。
每一個點的開心值改成1就好了
#include<iostream>
#include<cstdio>
using namespace std;
int n, t;
bool b[1000005];
int f[1000005][2],h[1000005];
struct Tree
{
int to, next;
}tree[200005];
void add(int x, int y)
{tree[++t] = (Tree){y, h[x]}; h[x] = t;}
void dp(int dep)
{
b[dep] = true;
f[dep][0] = 0;
f[dep][1] = 1;
for (int i = h[dep]; i; i = tree[i].next)
{
if (b[tree[i].to]) continue ;
b[tree[i].to] = true;
dp(tree[i].to);//算出兒子的值
f[dep][1] += min(f[tree[i].to][0], f[tree[i].to][1]);//動態轉移方程
f[dep][0] += f[tree[i].to][1];//也是一樣的
}
}
int main()
{
memset(f, 0x7f, sizeof(f));
int x, y;
scanf("%d", &n);
for (int i = 1; i < n; ++i)
{
scanf("%d%d",&x, &y);
add(x, y);
add(y, x);//加邊
}
dp(1);
printf("%d", min(f[1][0], f[1][1]));//求選或者不選好
}