zoukankan      html  css  js  c++  java
  • 树形dp(灯与街道)

    https://cn.vjudge.net/contest/260665#problem/E

    题意:

    给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮。每盏灯将照亮以它为一个端点的所有边。

    在灯的总数最小的前提下,被两盏灯同时被照亮的边数应该尽量大。

    solution:

    这是LRJ《训练指南》上的例题。

    这题教会了我一个很有用的技巧:有两个所求的值要优化,比如让a尽量小,b也尽量小

    那么可以转化为让 M*a+b尽量小,其中M应该是一个比“a的最大值和b的最小值之差”还要大的数

    最终的答案为ans/M, ans%M

    回到这题,要求放的灯总数最小,被两盏灯同时照亮的边数尽量大。

    因为每条边要么被一盏灯照亮,要么被两盏灯照亮,所以可以转换为:

    求:放的灯总数量最少,被一盏灯照亮的边数尽量少。

    就可以变成球 M*a+b 的最小值,a为放置的灯数量,b为被一盏灯照的边数

    f[u][1]表示u点放灯时的整个子树最小值
    f[u][0]表示u点不放灯时的整个子树最小值

    如果u放,那么u个子结点可以选择放,也可以不放,选择其中较小的值。如果选的是不照,就要增加一条只有一个灯照的边
    如果u不放,那么其子结点就必须选择要放,而且每条边都只有一个灯照

     1 /*************************************************************************
     2     > File Name: a.cpp
     3     > Author: QWX
     4     > Mail: 
     5     > Created Time: 2018/10/16 11:38:09
     6  ************************************************************************/
     7 
     8 
     9 //{{{ #include
    10 #include<iostream>
    11 #include<cstdio>
    12 #include<algorithm>
    13 #include<vector>
    14 #include<cmath>
    15 #include<queue>
    16 #include<map>
    17 #include<set>
    18 #include<string>
    19 #include<cstring>
    20 #include<complex>
    21 //#include<bits/stdc++.h>
    22 #define vi vector<int>
    23 #define pii pair<int,int>
    24 #define mp make_pair
    25 #define pb push_back
    26 #define first fi
    27 #define second se
    28 #define pw(x) (1ll << (x))
    29 #define sz(x) ((int)(x).size())
    30 #define all(x) (x).begin(),(x).end()
    31 #define rep(i,l,r) for(int i=(l);i<(r);i++)
    32 #define per(i,r,l) for(int i=(r);i>=(l);i--)
    33 #define FOR(i,l,r) for(int i=(l);i<=(r);i++)
    34 #define cl(a,b) memset(a,b,sizeof(a))
    35 #define fastio ios::sync_with_stdio(false);cin.tie(0);
    36 #define lson l , mid , ls
    37 #define rson mid + 1 , r , rs
    38 #define INF 0x3f3f3f3f
    39 #define LINF 0x3f3f3f3f3f3f3f3f
    40 #define ll long long
    41 #define ull unsigned long long
    42 #define dd(x) cout << #x << " = " << (x) << "," 
    43 #define de(x) cout << #x << " = " << (x) << "
    " 
    44 #define endl "
    "
    45 using namespace std;
    46 //}}}
    47 
    48 
    49 const int N=1007;
    50 const int Z=2000;
    51 
    52 int n,m;
    53 int dp[N][2];
    54 vi G[N];
    55 bool vis[N];
    56 
    57 
    58 void dfs(int u)
    59 {
    60     vis[u]=1;
    61     dp[u][0]=0;
    62     dp[u][1]=Z;
    63     for(auto v:G[u])if(!vis[v]){
    64         dfs(v);
    65         dp[u][0]+=dp[v][1]+1;
    66         dp[u][1]+=min(dp[v][1],dp[v][0]+1);
    67     }
    68 }
    69 
    70 int main()
    71 {
    72     fastio;
    73     int T;cin>>T;
    74     while(T--){
    75         rep(i,0,n)G[i].clear();
    76         cin>>n>>m;
    77         rep(i,0,m){
    78             int a,b; cin>>a>>b;
    79             G[a].pb(b);
    80             G[b].pb(a);
    81         }
    82         cl(vis,0);
    83         int ans=0;
    84         rep(i,0,n)if(!vis[i]){
    85             dfs(i);
    86             ans+=min(dp[i][0],dp[i][1]);
    87         }
    88         cout<<ans/Z<<" "<<m-ans%Z<<" "<<ans%Z<<endl;
    89     }
    90     return 0;
    91 }
    View Code

     

  • 相关阅读:
    04-基本的mysql语句
    03-MySql安装和基本管理
    02-数据库的概述
    MySql的前戏
    Python3连接MySQL数据库之pymysql模块的使用
    mockjs简单易懂
    GitHub Android 开源项目汇总 (转)
    国内云计算的缺失环节: GPU并行计算(转)
    HDFS+MapReduce+Hive+HBase十分钟快速入门
    同步和异步
  • 原文地址:https://www.cnblogs.com/klaycf/p/9798414.html
Copyright © 2011-2022 走看看