4000 UVa 10859 Placing Lampposts
2017-10-20 10:57
417 查看
题目描述 传送门
根据蓝书的思路:
设d(i,j)为以i为根节点的子树,i的父节点是否放灯(j=0,1分别为放和不放)的最小方案数。
因为在放置街灯a相等的情况下还有第二个比较条件,把条件统一为恰好被一盏灯照亮的边数c尽量小。设一个适当的数M,转换为最优化x=Ma+c,M的选取要使在a1<a2的情况下x1=Ma1+c1一定小于x2=Ma2+c2。
状态转移不难想。
总结:当最优化问题有多个关键字,可以统一成一个。
代码
根据蓝书的思路:
设d(i,j)为以i为根节点的子树,i的父节点是否放灯(j=0,1分别为放和不放)的最小方案数。
因为在放置街灯a相等的情况下还有第二个比较条件,把条件统一为恰好被一盏灯照亮的边数c尽量小。设一个适当的数M,转换为最优化x=Ma+c,M的选取要使在a1<a2的情况下x1=Ma1+c1一定小于x2=Ma2+c2。
状态转移不难想。
总结:当最优化问题有多个关键字,可以统一成一个。
代码
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=1005; const int M=2000; bool vis[maxn]; vector<int> g[maxn]; int d[maxn][2],n,m; void dfs(int u,bool root){ vis[u]=1; int put=0,notput=0; for(int i=0;i<g[u].size();i++) if(!vis[g[u][i]]){ dfs(g[u][i],0); put+=d[g[u][i]][1]; //u点放灯 notput+=d[g[u][i]][0]; //u点不放灯 } if(root) d[u][0]=min(notput,put+M); //根结点特殊 else d[u][0]=put+M+1; d[u][1]=min(notput+1,put+M); } int main(){ int t; cin>>t; while(t--){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++) g[i].clear(); for(int i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); g[a].push_back(b); g[b].push_back(a); } int ans=0; memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) if(!vis[i]){ dfs(i,1); ans+=d[i][0]; } printf("%d %d %d\n",ans/M,m-ans%M,ans%M); } return 0; }
相关文章推荐
- uva10859 - Placing Lampposts(动归)
- uva10859 - Placing Lampposts 无根树转有根树 DP
- UVA 10859 Placing Lampposts(树DP)
- UVa 10859 Placing Lampposts
- Uva 10859 - Placing Lampposts 树形dp
- UVaLive 10859 Placing Lampposts (树形DP)
- Uva 10859 - Placing Lampposts 树形DP+保持一个值最优的情况下维护另一个最优值
- UVA10859 Placing Lampposts
- Uva 10859 - Placing Lampposts 树形dp
- 【动态规划】【树形DP】[UVa 10859]Placing Lampposts
- UVA 10859 Placing Lampposts
- uva 10859 Placing Lampposts,树形dp
- UVa 10859 Placing Lampposts / 树形DP
- uva 10859 - Placing Lampposts(树形dp)
- Uva-10859-Placing Lampposts
- UVA 10859 Placing Lampposts 树形dp(水
- Uva10859 - Placing Lampposts
- UVa 10859 Placing Lampposts (树形DP)
- uva 10859 Placing Lampposts 树形dp
- UVA - 10859 Placing Lampposts 放置街灯