51nod 1314 定位系统 树形dp
2017-11-06 17:30
246 查看
题意
一个国家有N个城市(标号为0~N-1),这N个城市恰好由N-1条道路连接在一起(即N个城市正好构成一个树状结构)。这个国家的所有道路的长度都是1个长度单位。定义:两个城市间的距离是两个城市间的最短路的长度。现在这个国家想建立一套定位系统,让国家的公民能通过这套系统定位自己所在的城市。该系统由K个有编号的信号站构成,不妨将它们标号为0,1,2,3,…,K-1。每个信号站会放在一个城市中,每个城市最多安放一个信号站,每个信号站将不停的向外界发送信。(值得注意的是,信号站i不一定要安放在城市i中,例如:信号站2可以放在城市3中,也可以放城市4中)对于一个公民来说,如果他在城市X,那么他打开手机定位时,手机将收集K个信号站的信号,并根据这些信息生成一个K个元素的数组Dis[],其中Dis[i]记录着信号站i所在的城市与手机用户所在的城市(这里即为城市X)的距离。手机中的定位软件将根据该Dis[]数组来判断用户所在的城市编号。
由于信号站成本太高,该国家想尽可能少的购买信号站,那么问题来了,该国家最少需要安装多少个信号站才能唯一定位每一个城市?
友情提示:每个城市能被唯一定位的充要条件是,在每一个城市手机能接收到的数组Dis[]是互不相同的。
1<=N<=50
分析
首先枚举每一个点作为根,也就表示一定要放该点。在该点放了信号站以后,注意到如果在它的某一个子树里面放一个信号站,是影响不到其他子树内部的,但可以使这棵子树和其他子树分开。那么我至少要在d-1棵子树里面有信号站。d表示儿子数量。
我们就设solve(x,y)表示在以x为根的子树里面至少放y个信号站且把x的内部全部分开所需要的最少信号站。
然后再根据上面的策略往下dp即可。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int N=55; int n,cnt,last ,d ; char ch ; struct edge{int to,next;}e[N*2]; void addedge(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; } int solve(int x,int fa,int y) { int s=0,son=0; for (int i=last[x];i;i=e[i].next) if (e[i].to!=fa) son++; if (!son) return y; if (son==1) { for (int i=last[x];i;i=e[i].next) if (e[i].to!=fa) s+=solve(e[i].to,x,0); } else { int mn=n; for (int i=last[x];i;i=e[i].next) if (e[i].to!=fa) s+=solve(e[i].to,x,1),mn=min(mn,solve(e[i].to,x,0)-solve(e[i].to,x,1)); s+=mn; } if (s>=y) return s; else return s+y; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",ch+1); for (int j=1;j<=n;j++) if (ch[j]=='Y') addedge(i,j),d[j]++; } if (n==1) {puts("0");return 0;} int ans=n; for (int i=1;i<=n;i++) { int s=1; if (d[i]==1) { for (int j=last[i];j;j=e[j].next) s+=solve(e[j].to,i,0); } else { int mn=n; for (int j=last[i];j;j=e[j].next) s+=solve(e[j].to,i,1),mn=min(mn,solve(e[j].to,i,0)-solve(e[j].to,i,1)); s+=mn; } ans=min(ans,s); } printf("%d",ans); return 0; }
相关文章推荐
- 51nod 1405 树的距离之和 (两次dfs,树形dp)
- 51Nod-1412-AVL树的种类(树形dp)
- 51nod 1314 定位系统
- 51nod 1314 定位系统
- 51nod 1405 树的距离之和 【dfs--记忆dp??树形dp??】
- 51nod 1378 夹克老爷的愤怒(树形dp)
- 51nod 1500 苹果曼和树(树形dp)
- 51Nod - 1737 树形dp
- 51nod 1299 监狱逃离 树形dp
- 51nod 1405 树的距离之和【树形dp】
- 51Nod 1405 树的距离之和(树形dp)
- 51nod 1405 树的距离之和 (两次dfs,树形dp)
- 51nod 1424 零树(树形dp)
- 51nod 1405 树的距离之和 (树形dp)
- 51nod 苹果曼和树 (树形dp)
- 【树形DP】51Nod 1500 苹果曼和树
- 51Nod - 1677 树形dp + 组合数学
- 51nod 1405 树的距离之和 树形dp
- 51NOD-1405 树的距离之和(树形DP)
- 51nod 1378 夹克老爷的愤怒(树形DP+贪心)