UVa:10859 Placing Lampposts(树形DP)
来源:互联网 发布:js自动登录脚本 编辑:程序博客网 时间:2024/05/16 18:55
树形DP。
子问题可以分为两类,即在u为根节点且在u点放置灯时的最小灯数、u为根节点且不在u点放置灯时的最小灯数。
这样用dp【u】【1】,dp【u】【0】分别表示这两种情况。用edge【u】【0/1】【1/2】表示这两种情况时同时被灯照亮一条边、两条边的个数。
dp【u】【0】可以由u的所有子节点的dp【i】【1】之和转移而来,即当该结点的所有子节点都放灯时,这个点可以不放灯。同时计算edge【u】【0】【1/2】,edge【u】【0】【2】可以直接等于其子节点的edge【i】【1】【2】之和,edge【u】【0】【1】等于子节点edge【i】【0】【1】之和还要加上子节点数。
dp【u】【1】可以由u的所有子节点的min{dp【i】【0/1】}之和转移而来,注意当dp【i】【0】==dp【i】【1】时,要比较edge【i】【0】【2】与edge【i】【1】【2】的大小再做选择。同时计算edge【u】【1】【1/2】。
无向无环图要转换成有根树来做,这样递归的时候要判断不是父亲节点。
注意一个很坑的地方,题目给的图可能不连通。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>#define ll long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN 1005using namespace std;bool gl[MAXN][MAXN];bool node[MAXN];bool vis[MAXN][2];int dp[MAXN][2];int edge[MAXN][2][3];int n,m;int solve(int u,int v,int f){ if(vis[u][v]) return dp[u][v]; //edge[u][1]=edge[u][2]=0; vis[u][v]=true; if(v==0) { dp[u][0]=0; edge[u][0][1]=edge[u][0][2]=0; for(int i=0; i<n; ++i) if(gl[u][i]&&i!=f) { dp[u][0]+=solve(i,1,u); edge[u][0][2]+=edge[i][1][2]; edge[u][0][1]+=edge[i][1][1]+1; } return dp[u][0]; } else if(v==1) { dp[u][1]=0; edge[u][1][1]=edge[u][1][2]=0; for(int i=0; i<n; ++i) if(gl[u][i]&&i!=f) { int a=solve(i,1,u),b=solve(i,0,u); if(a<b) { dp[u][1]+=a; edge[u][1][2]+=edge[i][1][2]+1; edge[u][1][1]+=edge[i][1][1]; } else if(a>b) { dp[u][1]+=b; edge[u][1][2]+=edge[i][0][2]; edge[u][1][1]+=edge[i][0][1]+1; } else { dp[u][1]+=a; if(edge[i][1][2]>=edge[i][0][2]) { edge[u][1][2]+=edge[i][1][2]+1; edge[u][1][1]+=edge[i][1][1]; } else { edge[u][1][2]+=edge[i][0][2]; edge[u][1][1]+=edge[i][0][1]+1; } } } dp[u][1]++; return dp[u][1]; }}int main(){ int T; // freopen("outtt.txt","w",stdout); scanf("%d",&T); while(T--) { memset(gl,0,sizeof(gl)); memset(edge,0,sizeof(edge)); memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); memset(node,0,sizeof(node)); scanf("%d%d",&n,&m); for(int i=0; i<m; ++i) { int x,y; scanf("%d%d",&x,&y); gl[x][y]=gl[y][x]=true; node[x]=node[y]=true; } int ans=0,x=0,y=0; for(int i=0; i<n; ++i) if(node[i]&&!vis[i][0]) { if(solve(i,1,-1)<solve(i,0,-1)) { ans+=dp[i][1]; x+=edge[i][1][2]; y+=edge[i][1][1]; } else if(solve(i,1,-1)>solve(i,0,-1)) { ans+=dp[i][0]; x+=edge[i][0][2]; y+=edge[i][0][1]; } else { if(edge[i][1][2]>=edge[i][0][2]) { ans+=dp[i][1]; x+=edge[i][1][2]; y+=edge[i][1][1]; } else { ans+=dp[i][0]; x+=edge[i][0][2]; y+=edge[i][0][1]; } } } printf("%d %d %d\n",ans,x,y); } return 0;}
0 0
- Uva - 10859 - Placing Lampposts(树形dp)
- Uva 10859 - Placing Lampposts 树形dp
- uva 10859 Placing Lampposts 树形dp
- uva 10859 Placing Lampposts (树形dp)
- UVa 10859 Placing Lampposts / 树形DP
- uva 10859 - Placing Lampposts(树形dp)
- UVa:10859 Placing Lampposts(树形DP)
- Placing Lampposts - UVa 10859 树形dp
- UVA 10859 Placing Lampposts 树形dp(水
- uva 10859 Placing Lampposts 树形dp
- uva 10859 Placing Lampposts,树形dp
- UVA 10859 Placing Lampposts(树形DP)
- UVA 10859 Placing Lampposts--树形dp
- UVa 10859 Placing Lampposts (树形DP)
- 10859 - Placing Lampposts(树形dp)
- UVA--10859--Placing Lampposts--DP
- 【动态规划】【树形DP】[UVa 10859]Placing Lampposts
- UVA 题目10859 Placing Lampposts(树形DP)
- 日期结构体
- GProfile的总结
- Vector容器与iterator迭代器 之间的关联关系(六)
- Android 硬件抽象层的存在原因
- linux网络编程学习笔记之四 -----多线程并发服务端
- UVa:10859 Placing Lampposts(树形DP)
- fstream
- CI(CodeIgniter)框架入门教程——第一课 Hello World!
- 我的第六课:【设计模式】====迭代模式
- SVN: Could not resolve hostname
- 日期格式
- 【Steve Blank】中国创业现状(4):中关村——中国的硅谷
- MyEclipse编写内容利用tomcat在网页显示
- 整数去重排序