zoukankan      html  css  js  c++  java
  • UVa10895 Placing Lampposts

    UVa10895 Placing Lampposts

    链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34290

    【思路】

       树上DP+双重优化目标。

       本题的特点就是有两个优化目标分别为:在尽量少的结点放灯、在此前提下有被两盏灯照亮的边最多。

       首先进行转化:将第二个优化目标转化为在此前提下被一盏灯照亮的边最少。这样两个优化目标就都是求最小值。用一个hash(A,B)将两个新的优化目标AB映射到一个整数,转化为求这个整数的最小值,可以定义hash=A*M+B完成这个功能,M是一个较大数。

       树上DP。设d[i][j]表示以i为根的子树且有父节点状态为j时的最优值,注意用j记录父节点状态。有如下转移式:

          略。详见代码。

    【代码】

     1 #include<iostream>
     2 #include<cstring>
     3 #include<vector>
     4 using namespace std;
     5 
     6 const int maxn = 1000+10;
     7 const int INF=1<<30;
     8 const int M=2000;
     9 
    10 vector<int> G[maxn];
    11 int d[maxn][2];
    12 bool vis[maxn][2];
    13 int n,m; 
    14 
    15 inline void init() {
    16     for(int i=0;i<n;i++) G[i].clear();
    17     memset(vis,false,sizeof(vis));
    18     memset(d,0,sizeof(d)); 
    19 }
    20 
    21 int dp(int i,int j,int fa) {
    22     if(vis[i][j]) return d[i][j];
    23     vis[i][j]=true;
    24     int &ans=d[i][j];
    25     
    26     //无论j都可以在i上放置街灯 
    27     ans=M;              //放置一个街灯的价值 
    28     for(int k=0;k<G[i].size();k++) {
    29         int v=G[i][k];
    30         if(v!=fa) {
    31             ans += dp(v,1,i);
    32         }
    33     }
    34     if(!j && fa>=0) ans++;  //01
    35     
    36     if(j || fa<0)  //根也可以不放 
    37     {
    38         int sum=0;
    39         for(int k=0;k<G[i].size();k++) {
    40            int v=G[i][k];
    41            if(v!=fa) {
    42               sum += dp(v,0,i);
    43            }
    44         }
    45         if(fa>=0) sum++;             //10 //根不算 
    46         ans=min(ans,sum);  //两种情况取min 
    47     }
    48     
    49     return ans;
    50 }
    51 
    52 int main() {
    53     ios::sync_with_stdio(false);
    54     int T; cin>>T;
    55     while(T--)
    56     {
    57         cin>>n>>m;
    58         init();
    59         int u,v;
    60         for(int i=0;i<m;i++) {
    61             cin>>u>>v;
    62             G[u].push_back(v);
    63             G[v].push_back(u);
    64        }
    65        int ans=0;
    66        for(int i=0;i<n;i++) if(!vis[i][0]) {
    67                ans += dp(i,0,-1);
    68        }
    69        cout<<ans/M<<" "<<m-ans%M<<" "<<ans%M<<"
    ";
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    搭建公共DNS服务器[转]
    zabbix3.4 yum快速安装
    centos7安装图形化界面并远程连接
    记一次排查黑客入侵
    centos6安装图形界面并远程连接
    树莓派做NAS
    document.documentElement.scrollTop||document.body.scrollTop;
    矩阵连乘
    母函数详解
    Catalan 数
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4896138.html
Copyright © 2011-2022 走看看