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; }
弱者就是会被欺负呀