uvaoj 10859 - Placing Lampposts
2015-10-28 20:27
441 查看
题解:
1.将放置最少的街灯等价为最多地方没有放置街灯个数为x
2.被两个街灯照亮的边数为b
3.k > b的最大值
4.y = kx + b,找到最大的y
5.树形dp
总结:
1.将问题归一化,减少了很多无谓的操作和变量,将两个变量编码成一个数值
1.将放置最少的街灯等价为最多地方没有放置街灯个数为x
2.被两个街灯照亮的边数为b
3.k > b的最大值
4.y = kx + b,找到最大的y
5.树形dp
总结:
1.将问题归一化,减少了很多无谓的操作和变量,将两个变量编码成一个数值
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define MAXN 1010 #define K 2000 #define INF 0x3f3f3f3f #define F(i,n) for(int i = 0;i < (n);i++) int d[MAXN][2],vis[MAXN]; vector<int>vec[MAXN]; int n,_,m,u,v; void dfs(int u) { vis[u] = 1; int ans0 = 0,ans1 = 0,cnt1 = 0; F(i,vec[u].size()) { int v = vec[u][i]; if(vis[v])continue; dfs(v); ans0 += d[v][1]; if(d[v][0] > d[v][1])ans1 += d[v][0]; else { ans1 += d[v][1]; cnt1 ++; } } d[u][0] = ans0 + K; d[u][1] = ans1 + cnt1; } int main() { cin >> _; while(_--) { cin >> n >> m; for(int i = 0;i < n;i++)vec[i].clear(); memset(vis,0,sizeof(vis)); for(int i = 0;i < m;i++) { cin >> u >> v; vec[u].push_back(v); vec[v].push_back(u); } int ans = 0; F(i,n)if(!vis[i]) { dfs(i); ans += max(d[i][0],d[i][1]); } int ans1 = n - ans / K; int ans2 = ans % K; cout << ans1 << " " << ans2 << " " << m - ans2 << endl; } }
相关文章推荐
- 树形DP 或 最小顶点覆盖=最大匹配(双向图)(HDU 1053)
- [BZOJ1017][JSOI2008][树形DP]魔兽地图DotR
- ZOJ3824 Fiber-optic Network
- hihocoder #1035 : 自驾旅行 III 树形DP
- POJ 3342
- URAL1018
- hdu1561 zoj3201
- poj 3107 Godfather
- zoj3201Tree of Tree
- Codeforces Round #135 (Div. 2)VD. Choosing Capital for Treeland
- POJ 1848 Tree
- 树形dp简单总结
- Party at Hali-Bula
- zoj cut the tree(树形dp,小细节真的很多)
- poj 2486 Apple Tree(树形dp)
- poj 1155 TELE(树形泛化背包dp)
- 树形DP
- HDU 1520 Anniversary party (树形dp) 解题报告
- POJ 1463 Strategic game (树形DP) 解题报告
- ACM入门题目(北大ACM教材)