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

    Placing Lampposts

     给你一个森林。选择一些点放灯,每个灯可以照亮所在点周围的所有边。优先最小化灯的数量,使所有边被照亮,然后最大化被两盏灯照亮的边的个数

    由于   被两盏灯照亮的边的个数 + 被一盏灯照亮的边的个数 = 边数

    把“最大化被两盏灯照亮的边的个数”转换为“最小化被一盏灯照亮的边的个数

     

    “若有两个变量v1,v2,最优化v1的前提下最优化v2,可以设置为最优化Mv1 + v2,M是一个比max(v2) - min(v2)大的数”.这样的话v1增加1,增加量就一定比v2增加量大了

    然后常规树形dp即可

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <queue>
     7 #include <vector>
     8 #define min(a, b) ((a) < (b) ? (a) : (b))
     9 #define max(a, b) ((a) > (b) ? (a) : (b))
    10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 }
    15 inline void read(int &x)
    16 {
    17     x = 0;char ch = getchar(), c = ch;
    18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
    19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    20     if(c == '-') x = -x;
    21 }
    22 
    23 const int INF = 0x3f3f3f3f;
    24 const int MAXN = 10000 + 10;
    25 const int K = 2000;
    26 
    27 struct Edge
    28 {
    29     int u,v,nxt;
    30     Edge(int _u, int _v, int _nxt){u = _u;v = _v;nxt = _nxt;}
    31     Edge(){}
    32 }edge[MAXN << 1];
    33 int head[MAXN], cnt;
    34 inline void insert(int a, int b)
    35 {
    36     edge[++cnt] = Edge(a,b,head[a]);
    37     head[a] = cnt;
    38 }
    39 
    40 int t,n,m,b[MAXN],ans,dp[MAXN][2],root;
    41 
    42 //设x为被一盏灯照亮的边,y表示灯的数量,最小化Ky + x 
    43 //dp[i][0]表示第i个点的父亲不放灯,i子树中的边和i与父亲的边最小Ky + x
    44 //dp[i][1]表示第i个点的父亲放灯,i子树中的边和i与父亲的边最小的Ky + x
    45 
    46 void dfs(int x)
    47 {
    48     b[x] = 1;
    49     int tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
    50     for(register int pos = head[x];pos;pos = edge[pos].nxt)
    51     {
    52         int v = edge[pos].v;
    53         if(!b[v]) dfs(v);
    54         
    55         //dp[x][0]父节点不放灯 
    56         //这个点不放灯 
    57         if(root == x) tmp1 += dp[v][0];
    58         //这个点放灯
    59         tmp2 += dp[v][1];
    60         
    61         //dp[x][1]父节点放灯 
    62         //这个点不放灯
    63         tmp3 += dp[v][0]; 
    64         //这个点放灯 
    65         tmp4 += dp[v][1];
    66     } 
    67     tmp2 += K;tmp4 += K;
    68     if(root != x) ++ tmp2, ++ tmp3, tmp1 = INF;
    69     dp[x][0] = min(tmp1, tmp2);
    70     dp[x][1] = min(tmp3, tmp4);
    71     return;
    72 } 
    73 
    74 int main()
    75 {
    76     read(t);
    77     for(;t;--t)
    78     {
    79         read(n), read(m);
    80         memset(b, 0, sizeof(b));
    81         memset(head, 0, sizeof(head));
    82         memset(dp, 0, sizeof(dp));ans = 0; 
    83         for(register int i = 1;i <= m;++ i)
    84         {
    85             int tmp1,tmp2;read(tmp1), read(tmp2);
    86             ++ tmp1, ++ tmp2;
    87             insert(tmp1, tmp2), insert(tmp2, tmp1);
    88         }
    89         for(register int i = 1;i <= n;++ i)
    90             if(!b[i]) root = i, dfs(i), ans += dp[i][0];
    91          printf("%d %d %d
    ", ans/K, m - ans%K, ans%K);
    92     }
    93     return 0;
    94 }
    UVA10859
  • 相关阅读:
    Java面试题(转)
    哪种方式更适合在React中获取数据?
    vue学习之深入响应式原理
    还不会用FindBugs?你的代码质量很可能令人堪忧
    几道大数据面试题(转)
    【Medium翻译】Java抽象类有什么用?
    深入理解Kafka必知必会(上)
    (八十六)c#Winform自定义控件-表格优化(转载)
    IDEA 配置及常用快捷键
    Markdown 复杂公式&常用符号
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8300969.html
Copyright © 2011-2022 走看看