bzoj1596[Usaco2008 Jan]电话网络*
题意:
在一棵树中选最少的点建塔,使得每个点都有塔或相邻点有塔。n≤10000。
题解:
贪心。dfs时对于每个当前点,在dfs完它的所有子节点后如果它以及它的儿子以及它的父亲没塔,则在它父亲处建塔。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define maxn 10010 7 using namespace std; 8 9 inline int read(){ 10 char ch=getchar(); int f=1,x=0; 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 12 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 13 return f*x; 14 } 15 struct e{int t,n;}es[2*maxn]; int ess,g[maxn]; 16 void pe(int f,int t){ 17 es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess; 18 } 19 int n,ans; bool cov[maxn]; 20 void dfs(int x,int fa){ 21 bool f=0; 22 for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa){ 23 dfs(es[i].t,x); if(cov[es[i].t])f=1; 24 } 25 if(!f&&!cov[x]&&!cov[fa])ans++,cov[fa]=1; 26 } 27 int main(){ 28 n=read(); inc(i,1,n-1){int x=read(),y=read(); pe(x,y);} dfs(1,0); printf("%d",ans); return 0; 29 }
20161108