洛谷 P2899 [USACO08JAN]Cell Phone Network G
题目大意
有N个点,N-1条边(也就是一棵树),对于任意一个节点,要么自己建一个信号站,要么父节点或子节点建一个信号站,问需要信号站个数最少是多少?
分析
看到这题,感觉跟没有上司的舞会很像,所以只需要在加一种状态就行了。
自己(x),子节点(y),父节点(fa)中必须要有一个点建信号站。
定义状态:
f[x][0] 表示在i点建一个信号站需要的最少信号站数
f[x][1] 表示在i父节点建一个信号站需要的最少信号站数
f[x][2] 表示在i子节点建一个信号站需要的最少信号站数
状态转移:
y,z∈son[x],y≠z
1.f[x][0]=∑min(f[y][0],f[y][1],f[y][2])
这种状态表示在x放置信号站,可以选择在子节点放置(f[y][0]),子节点可以选择被x包养(f[y][1]),子节点也可以选择被自己儿子赡养(f[y][2])
2.f[x][1]=∑min(f[y][0],f[y][2])
这种状态表示在fa放置信号站,那么子节点只能选择在自己这里放置(f[y][0]),或在自己子节点放置(f[y][2])
3.f[x][2]=min(∑min(f[y][0],f[y][2])+f[z][0])
此状态表示在y放置信号站,我们只要选择一个子节点放置就行了,其余子节点可以选择把信号站放在自己这,也可以选择放在自己子节点处
对于点y,如果此时f[x][2]=f[y][0]+∑j∈son[x],j≠ymin(f[j][0],f[j][2])不是最优的,
一定存在另一个点z满足f[z][0]+∑j∈son[x],j≠zmin(f[j][0],f[j][2]) < f[y][0]+∑j∈son[x],j≠ymin(f[j][0],f[j][2])
整理得,f[z][0]-min(f[z][0],f[z][2])< f[y][0]-min(f[y][0],f[y][1])
所以对于最优的y ,只要满足 f[y][0]-min(f[y][0],f[y][2]) 是所有子节点中最小的就行了 ,所以我们可以先让f[0][0]=INF来转移
最后 只要在 f[1][0]与f[1][2] 中选择一个最小值即可
#include<bits/stdc++.h> #define N 10005 #define INF 0x3f3f3f3f using namespace std; int n,tot; int f[N][3]; //f[i][0] 表示在i点建一个信号站 //f[i][1] 表示在i父节点建一个信号站 //f[i][2] 表示在i子节点建一个信号站 int Head[N],to[N<<1],Next[N<<1]; bool vis[N]; void add(int u,int v){ to[++tot]=v; Next[tot]=Head[u]; Head[u]=tot; } void dfs(int x,int fa){ vis[x]=1; f[x][0]=1; int s=0; for(int i=Head[x];i;i=Next[i]){ int y=to[i]; if(vis[y]) continue; dfs(y,x); f[x][0]+=min(f[y][0],min(f[y][1],f[y][2])); f[x][1]+=min(f[y][0],f[y][2]); if(f[s][0]-min(f[s][0],f[s][2])>f[y][0]-min(f[y][0],f[y][2])) s=y; } f[x][2]=f[s][0]; for(int i=Head[x];i;i=Next[i]){ int y=to[i]; if(y==fa||y==s) continue; f[x][2]+=min(f[y][0],f[y][2]); } } int main(){ scanf("%d",&n); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } f[0][0]=INF; dfs(1,0); printf("%d\n",min(f[1][0],f[1][2])); return 0; }
本文作者:Aurora-JC
本文链接:https://www.cnblogs.com/jiangchen4122/p/15889048.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步