1010 电话网络 最小支配集
链接:https://ac.nowcoder.com/acm/contest/25022/1010
来源:牛客网
题目描述
Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流。不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号。所有的N块草地按1..N 顺次编号。 所有草地中只有N-1对是相邻的,不过对任意两块草地A和B(1 <= A <= N; 1 <= B <= N; A != B),都可以找到一个以A开头以B结尾的草地序列,并且序列中相邻的编号所代表的草地相邻。无线电通讯塔只能建在草地上,一座塔的服务范围为它所在的那块草地,以及与那块草地相邻的所有草地。 请你帮FJ计算一下,为了建立能覆盖到所有草地的通信系统,他最少要建多少座无线电通讯塔。
输入描述:
* 第1行: 1个整数,N
* 第2..N行: 每行为2个用空格隔开的整数A、B,为两块相邻草地的编号
输出描述:
* 第1行: 输出1个整数,即FJ最少建立无线电通讯塔的数目
分析
就是问最小的让所有点都能被覆盖的数量。
跟1003完全一样的最小支配集问题。
//-------------------------代码---------------------------- //#define int ll const int N = 2e6+10; int n,m; int ne[N],e[N],w[N],h[N],idx; int dp[N][3]; void add(int a,int b) { e[idx] = b,ne[idx] = h[a],h[a] = idx ++ ; } void dfs(int u,int fa) { dp[u][0] = 1; dp[u][1] = 0; dp[u][2] = 0; int inc = inf; for(int i = h[u];~i;i=ne[i]) { int j = e[i]; if(j == fa) continue; dfs(j,u); dp[u][0] += min({dp[j][1],dp[j][2],dp[j][0]}); dp[u][2] += min(dp[j][1],dp[j][0]); dp[u][1] += min(dp[j][0],dp[j][1]); inc = min(inc,dp[j][0] - dp[j][1]); } if(inc < 0) inc = 0; dp[u][1] += inc; } void solve() { cin>>n; ms(h,-1); fo(i,1,n-1) { int a,b;cin>>a>>b; add(a,b); add(b,a); } dfs(1,-1); cout<<min(dp[1][1],dp[1][0])<<endl; } signed main(){ clapping();TLE; // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------