【bzoj1369】【Baltic2003】【Gem】【树形dp】
2016-05-21 15:30
609 查看
Description
给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小。Input
先给出一个数字N,代表树上有N个点,N<=10000 下面N-1行,代表两个点相连Output
最小的总权值Sample Input
107 5
1 2
1 7
8 9
4 1
9 7
5 6
10 2
9 3
Sample Output
14题解:
一共需要的颜色不超过logn个.
设f[i][j]表示i这棵子树,根节点的颜色是j的最小代价.
dp即可.
代码:
#include<iostream> #include<cstdio> #include<cstring> #define N 10010 using namespace std; int point ,next[N<<1],n,cnt,v ,x,y,f [20],ans; struct use{int st,en;}e[N<<1]; void add(int x,int y){ next[++cnt]=point[x];point[x]=cnt; e[cnt].st=x;e[cnt].en=y; } void dp(int x,int fa){ for (int i=point[x];i;i=next[i]) if (e[i].en!=fa){ dp(e[i].en,x); for(int j=1;j<=14;j++){ int mn=1000000; for (int k=1;k<=14;k++) if (k!=j) mn=min(mn,f[e[i].en][k]); f[x][j]+=mn; } } for (int i=1;i<=14;i++) f[x][i]+=i; } int main(){ scanf("%d",&n); for (int i=1;i<n;i++){ scanf("%d%d",&x,&y); add(x,y);add(y,x); } dp(1,0);ans=1000000; for (int i=1;i<=14;i++) ans=min(ans,f[1][i]); cout<<ans<<endl; }
相关文章推荐
- forward和include的区别
- JAVA并发编程学习笔记之CLH队列锁
- [置顶] 正态分布的由来
- 多台主机鼠键共享工具syngery的配置使用
- Axure 实现批量的勾选和反选
- PHP+MySql+jQuery实现的"顶"和"踩"投票功能
- javascript检测移动设备横竖屏
- JAVA并发编程学习笔记之Unsafe类
- AFHTTPSessionManager网络下载示例
- 分类算法(6) ---- 支持向量机(SVM)
- leetcode 之Copy List with Random Pointer(23)
- JAVA并发编程学习笔记之MCS队列锁
- L3-002. 堆栈(线段树)
- 马哥公开课
- Mysql 5.7.12 免安装版配置
- 征服go开始
- CppUnit的安装及使用指南
- hash算法 (hashmap 实现原理)
- python api testing接口自动发邮件
- 使用Java调用ElasticSearch提供的相关API进行数据搜索完整实例演示