轮舞前夕
2015-08-12 20:17
246 查看
题意
给你一棵树,求最小点覆盖集的元素个数和方案个数。分析
设f[i][0],f[i][1],f[i][2]f[i][0],f[i][1],f[i][2]分别为0:以ii节点为根节点的子树除了ii节点都被覆盖的最小值;
1:以ii节点为根节点的子树都被覆盖,且ii节点不在集合中的最小值。
2:以ii节点为根节点的子树都被覆盖,且ii节点在集合中的最小值。
转移显然,方案数随ff转移即可。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int N = 1e5 + 10; const LL P = 1e9 + 7; int n,tot; int to[N * 2],next[N * 2],g ; int f [3],F[3]; LL cnt [3],nt[3]; void add(int x,int y) { to[++ tot] = y; next[tot] = g[x]; g[x] = tot; } int calc(int x,int y) { if (x == 2) return 2; if (y == 2 || x == 1 && y == 1) return 1; return 0; } void dfs(int u,int fa) { for (int i = 0;i <= 2;i ++) cnt[u][i] = 1; f[u][2] = 1,f[u][1] = P,f[u][0] = 0; for (int i = g[u];i;i = next[i]) { int v = to[i]; if (v == fa) continue; dfs(v,u); for (int j = 0;j <= 2;j ++) F[j] = P,nt[j] = 0; for (int j = 0;j <= 2;j ++) for (int k = 0;k <= 2;k ++) { if (j != 2 && k == 0) continue; int l = calc(j,k); F[l] = min(F[l],f[u][j] + f[v][k]); } for (int j = 0;j <= 2;j ++) for (int k = 0;k <= 2;k ++) { if (j != 2 && k == 0)continue; int l = calc(j,k); if (f[u][j] + f[v][k] == F[l]) nt[l] = (nt[l] + cnt[u][j] * cnt[v][k]) % P; } memcpy(f[u],F,sizeof(f[u])); memcpy(cnt[u],nt,sizeof(nt)); } } int main() { scanf("%d",&n); for (int i = 1;i < n;i ++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(1,0); int ans = min(f[1][1],f[1][2]); int ansn = 0; for (int i = 1;i <= 2;i ++) if (f[1][i] == ans) ansn = (ansn + cnt[1][i]) % P; printf("%d\n%d",ans,ansn); }
相关文章推荐
- 2015/08/12/HTTPURL中GET和POST/HTTPClient中的GET和POST
- C#学习之While循环
- UITouch 摇晃手势启动器
- Balanced Binary Tree
- Java——StringBuffer
- Java心得12
- 四层和七层负载均衡的区别
- HDU 5373 The shortest problem
- linux桌面之菜单与文件关联简介
- [Leetcode] Add Two Numbers
- Android LayoutCast 初探
- python中的map、filter、reduce函数
- 客户端与服务器数据传输的两种方式
- eclipse里配置maven
- mahout的安装,配置及聚类测试
- dfs+剪枝 poj1011
- 2014华为机试题
- the steps that may be taken to solve a feature selection problem:特征选择的步骤
- MyEclipse2014安装svn插件的方式:
- java Http编程小结