zoukankan      html  css  js  c++  java
  • UVA 10859 Placing Lampposts 树形DP

    dfs+记忆化搜索,白书上给了一种很神的存答案的方式,要同时保存两个值,可以将一个值乘以一个大整数加上另外一个。

    具体状态转移见注释

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <deque>
    #include <bitset>
    #include <list>
    #include <cstdlib>
    #include <climits>
    #include <cmath>
    #include <ctime>
    #include <algorithm>
    #include <stack>
    #include <sstream>
    #include <numeric>
    #include <fstream>
    #include <functional>
    
    using namespace std;
    
    #define MP make_pair
    #define PB push_back
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<int> VI;
    typedef pair<int,int> pii;
    const int INF = INT_MAX / 3;
    const double eps = 1e-8;
    const LL LINF = 1e17;
    const double DINF = 1e60;
    const int maxn = 1005;
    VI e[maxn];
    int n, m, vis[maxn][2], note[maxn][2];
    
    int dfs(int i, int j, int f) {
        if(vis[i][j]) return note[i][j];
        vis[i][j] = 1;
        int &ret = note[i][j] = INF;
        //如果当前节点不放灯(父亲节点必须放灯)
        //总数为每一个节点的和 × 2000 + 1
        //需要对根节点进行特判
        int sum = f == -1 ? 0 : 1, mm = e[i].size();
        if(j) {
            for(int nx = 0;nx < mm;nx++) if(e[i][nx] != f) {
                sum += dfs(e[i][nx], 0, i);
            }
            ret = sum;
        }
        //当前节点放灯
        //总数为每一个节点的和*2000,然后如果父亲节点没有灯,再+1
        sum = j == 0 ? 1 : 0;
        for(int nx = 0;nx < mm;nx++) if(e[i][nx] != f) {
            sum += dfs(e[i][nx], 1, i);
        }
        sum += 2000;
        ret = min(sum,ret);
        return ret;
    }
    
    int main() {
        int T; scanf("%d",&T);
        while(T--) {
            memset(vis,0,sizeof(vis));
            memset(note,0,sizeof(note));
            scanf("%d%d",&n,&m);
            for(int i = 0;i < n;i++) e[i].clear();
            for(int i = 0;i < m;i++) {
                int a,b; scanf("%d%d",&a,&b);
                e[a].PB(b); e[b].PB(a);
            }
            //当前节点,父节点有没有点亮,父节点编号
            //dfs(i,j,k)
            //枚举森林中的每一棵树
            int ans = 0;
            for(int i = 0;i < n;i++) if(!vis[i][0]) {
                ans += dfs(i,1,-1);
            }
            printf("%d %d %d
    ",ans / 2000,m - ans % 2000,ans % 2000);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Azure DevOps上使用git push --force遇到的问题
    Redis常用的一些基本命令
    [Vue warn]: Error in v-on handler: "TypeError: this.onConfirm(...).then is not a function"
    政采云:数据可视化探索之SpreadJS 表格控件
    用Java写一个折半查找
    springboot 集成hibernate 多数据源链接
    java 自定义注解
    幻读:听说有人认为我是被MVCC干掉的
    懵了!女朋友突然问我MVCC实现原理
    不会MySQL索引,面试官让回家等通知!
  • 原文地址:https://www.cnblogs.com/rolight/p/3959200.html
Copyright © 2011-2022 走看看