[51nod1314] 定位系统
Posted HLX_Y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[51nod1314] 定位系统相关的知识,希望对你有一定的参考价值。
题意:给你一棵树,要求你选择一些点建立信号站,使得每一个点到这些信号站的距离数组dis都不一样(注意是数组不一样)
题解:
树形dp
1、若在两点x,y建立信号站,那么x->y路径上的所有点的dis数组都不一样
2、考虑选择一个点为根并标记,那么尽量选择叶子标记,这样链越长,贡献越大
3、若某个结点的子树为多叉树,那么至多可以有一条链形子树的叶子不需要标记,因为这条链上的结点可以被其他子树标记的点影响
4、特判:n=1时,答案为0。当树退化成链时,当前的根节点不需要标价
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define ll long long #define N 55 using namespace std; int e_num,dp[N],t[N],nxt[N*2],to[N*2],h[N]; char s[55]; int gi() { int x=0,o=1; char ch=getchar(); while(ch!=‘-‘ && (ch<‘0‘ || ch>‘9‘)) ch=getchar(); if(ch==‘-‘) o=-1,ch=getchar(); while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return o*x; } void add(int x, int y) { nxt[++e_num]=h[x],to[e_num]=y,h[x]=e_num; } void dfs(int u, int fa) { dp[u]=0,t[u]=0; int flg=0; for(int i=h[u]; i; i=nxt[i]) { int v=to[i]; if(v==fa) continue; if(!t[u]) t[u]=1; else t[u]=2; dfs(v,u); dp[u]+=dp[v]; if(t[v]<=1) flg=1;//有一个子树为链 else if(t[v]) t[u]=2;//表示它并非一条链的形式 } if(t[u]==2) dp[u]-=flg; if(!t[u]) dp[u]=1; } int main() { int n=gi(),ans=1<<30; if(n==1) {puts("0");return 0;} for(int i=1; i<=n; i++) { scanf("%s", s+1); for(int j=1; j<=n; j++) { if(s[j]==‘Y‘) add(i,j); } } for(int i=1; i<=n; i++) { dfs(i,0); dp[i]+=(t[i]==2); ans=min(ans,dp[i]); } printf("%d", ans); return 0; }
以上是关于[51nod1314] 定位系统的主要内容,如果未能解决你的问题,请参考以下文章