bzoj1596 电话网络
Description
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计算一下,为了建立能覆盖到所有草地的通信系统,他最少要建多少座无线电通讯塔。
Input
* 第1行: 1个整数,N
* 第2..N行: 每行为2个用空格隔开的整数A、B,为两块相邻草地的编号
Output
* 第1行: 输出1个整数,即FJ最少建立无线电通讯塔的数目
Sample Input
5
1 3
5 2
4 3
3 5
1 3
5 2
4 3
3 5
虽然看起来是树dp,但是明明可以贪心。但是由于我dp太烂,还是打dp吧。
然后在4ms的时候wa了,看了很久没有看出bug来,最后发现是INF设的太大,加爆掉了变成负数一取min就完了
说明取INF不是越大越好啊
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1e4+10,INF=maxn;//
int n,ans[3][maxn];
//ans[i][0]:以i为根的子树中所有点均被覆盖且草地i上无信号塔所需的最小塔数(i被其儿子覆盖)
//ans[i][1]:以i为根的子树中所有点均被覆盖且草地i上有信号塔所需的最小塔数
//ans[i][2]:以i为根的子树中除i点以外其余点均被覆盖所需的最小塔数
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
int fir[maxn],nxt[2*maxn],to[2*maxn],e=0;
void add(int x,int y) {
to[++e]=y;nxt[e]=fir[x];fir[x]=e;
to[++e]=x;nxt[e]=fir[y];fir[y]=e;
}
int fa[maxn];
void dfs(int pos) {
ans[0][pos]=INF;ans[1][pos]=1;
int xx,sum=0,z;//
for(int y=fir[pos];y;y=nxt[y]) {
z=to[y]; if(z==fa[pos]) continue;
fa[z]=pos; dfs(z);
xx=min(ans[0][z],ans[1][z]); sum+=xx;
ans[1][pos]+=min(xx,ans[2][z]); ans[2][pos]+=ans[0][z];
ans[0][pos]=min(ans[0][pos],ans[1][z]-xx);
}
ans[0][pos]+=sum;
}
int main() {
n=read(); int x,y;
for(int i=1;i<n;++i) {
x=read();y=read();
add(x,y);
}
dfs(1);
printf("%d",min(ans[0][1],ans[1][1]));
return 0;
}
弱者就是会被欺负呀

浙公网安备 33010602011771号