UVA1218--树形DP
2015-09-16 21:12
288 查看
没有看书和题解做的一道树形DP题,思路很清晰。。只是debug上花了很久的时间才发现看错了条件。。并不是每个点都只能和一台服务器相邻,而是非服务器的点只能和一台服务器相邻。。看错了一个条件差距大了去了。。
设d[u][col][fcol]代表节点为u,颜色为col,父亲节点为fa,颜色为fcol时的最小服务器数量。col值为1代表服务器,0代表计算机,则转移方程:
d[u][1][x]:只要col为1,则每个节点既可以是服务器也可以不是;
d[u][0][1]:节点u是不服务器,fa是服务器,则u的子节点都不是服务器;
d[u][0][0]:节点u和fa都不是服务器
状态转移:dp(u,1,x)=sum{min(dp(v,0,u,1),dp(v,1,u,1))} + 1;
dp(u,0,1) = sum{dp(v,0,u,0)};
dp(u,0,0)=min{dp(u,0,1)-dp(v,0,0)+dp(v,1,x)};
设d[u][col][fcol]代表节点为u,颜色为col,父亲节点为fa,颜色为fcol时的最小服务器数量。col值为1代表服务器,0代表计算机,则转移方程:
d[u][1][x]:只要col为1,则每个节点既可以是服务器也可以不是;
d[u][0][1]:节点u是不服务器,fa是服务器,则u的子节点都不是服务器;
d[u][0][0]:节点u和fa都不是服务器
状态转移:dp(u,1,x)=sum{min(dp(v,0,u,1),dp(v,1,u,1))} + 1;
dp(u,0,1) = sum{dp(v,0,u,0)};
dp(u,0,0)=min{dp(u,0,1)-dp(v,0,0)+dp(v,1,x)};
#include<cstdio> #include<iostream> #include<algorithm> #include<vector> #include<cstring> #include<cmath> #include<sstream> #include<climits> #define INF 1000000 using namespace std; const int maxn = 10005; int n; int u,v; vector<int> g[maxn]; int ed; int d[maxn][2][2]; int dp(int u,int col,int fa,int fcol) { if(d[u][col][fcol] > -1) return d[u][col][fcol]; if(col == 1){ //if(g[u].size() == 1&&g[u][0] == fa) return d[u][col][fcol] = 1; int sum = 1; for(int i = 0; i < g[u].size(); ++i){ int v = g[u][i]; if(v != fa) sum+=min(dp(v,0,u,1),dp(v,1,u,1)); } return d[u][col][fcol] = sum; } else if(fcol == 1&&col == 0){ //if(g[u].size() == 1&&g[u][0] == fa) return d[u][col][fcol] = 0; int sum = 0; for(int i = 0; i < g[u].size(); ++i){ int v = g[u][i]; if(v != fa){ sum+=dp(v,0,u,0); } } return d[u][col][fcol] = sum; } else if(fcol == 0&&col == 0) { //if(g[u].size() == 1&&g[u][0] == fa) return d[u][col][fcol] = INF; int sum = dp(u,0,fa,1);//cout<<sum<<"***"<<endl; int ans = INF; for(int i = 0; i < g[u].size(); ++i){ int v = g[u][i]; if(v != fa){ ans = min(ans,sum + dp(v,1,u,0)- dp(v,0,u,0)); } } return d[u][col][fcol] = ans; } } int main() { //freopen("in","r",stdin); while(~scanf("%d",&n)) { memset(d,-1,sizeof(d)); for(int i = 1; i <= n-1; ++i) { scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } cout<<min(dp(1,0,-1,0),dp(1,1,-1,0))<<endl; for(int i = 1; i <= n; ++i) g[i].clear(); cin>>ed; if(ed == -1) return 0; } }
相关文章推荐
- JS 图像上传前实现压缩
- Huffman
- 傅里叶变换 【完整版】
- Java文件操作大全
- 程序员发展路径
- 2015区域赛长春网络赛 Travel
- 笔试题:C语言中的字符串问题
- hdu 5444 Elven Postman
- MFC中多个子菜单对应同一个消息响应函数
- Leetcode: 第四题 Median of Two Sorted Arrays
- ios开发-新浪微博10-(下拉菜单的二次封装 完整版)
- poj 3087 Shuffle'm Up (kuangbin带你飞--简单搜索)
- 设计模式初学者笔记:Factory Method模式
- PHP中文乱码的常见解决方法总结
- RILD QCRIL的关系
- ImageDownLoaderAndKVO
- SSH-Struts(两)—调节器(ActionServlet)
- 【待】1.4 Write a method to replace all spaces in a string with'%20'.
- hdu 4540 威威猫系列故事——打地鼠
- Java中的“别名现象”