UVA10859 Placing Lampposts

题意:给一个无向无环图(n<1000),在尽量少的节点上放灯,使得所有边都被照亮,灯可以照亮相邻的边,在灯数最小的前提下,使得被两盏灯照亮的边最多,输出灯数以及被两盏灯照亮的边数,及剩下的边数

题解:树形dp,树上的优化,灯选或不选dp[i][0]和dp[i][1],主要的问题在于多个限制条件,这里就有一个小技巧,可以把两个限制条件变为一个数,b = M*a+c,a是灯的数量,c是一盏灯的数量,M是一个很大的数,那么这样a就占据主导作用,接下来就是树形dp具体看代码,注意初始化

#include <bits/stdc++.h>
#define ll long long
#define maxn 1100
#define M 2000
using namespace std;
vector<int >G[maxn];
int dp[maxn][2], dir[maxn];
int dfs(int x){
    dir[x] = 1;
    dp[x][0] = 0;
    dp[x][1] = M;
    for(int i=0;i<G[x].size();i++){
        int u = G[x][i];
        if(dir[u]) continue;
        dfs(u);
        dp[x][1] += min(dp[u][1], dp[u][0]+1);
        dp[x][0] += dp[u][1]+1;
    }
    return min(dp[x][0], dp[x][1]);
}
int main(){
    int T, n, m, a, b, ans;
    scanf("%d", &T);
    while(T--){
        memset(dir, 0, sizeof(dir));
        ans = 0;
        scanf("%d%d", &n, &m);
        for(int i=0;i<n;i++) G[i].clear();
        for(int i=0;i<m;i++){
            scanf("%d%d", &a, &b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        for(int i=0;i<n;i++)
            if(!dir[i])
                ans += dfs(i);
        printf("%d %d %d\n", ans/M, m-ans%M, ans%M);
    }
    return 0;
}
时间: 2024-11-09 04:36:35

UVA10859 Placing Lampposts的相关文章

UVA 10859 - Placing Lampposts 树形DP、取双优值

                          Placing Lampposts As a part of the mission ‘Beauti?cation of Dhaka City’, the government has decided to replace all theold lampposts with new expensive ones. Since the new ones are quite expensive and the budget is notup to

uva 10859 Placing Lampposts,树形dp

// uva 10859 Placing Lampposts // 树形dp // // 题目的意思是一个无向无环图中,有一些顶点和一些边 // 要在顶点上放置灯笼(灯笼可以照亮与它相邻接的点), // 使得所有的边都能被灯笼照亮,其中可能有一些边被两个灯笼 // 照亮,则要求使得所有边都被灯笼照亮所需灯笼的最小值, // 并且,此时边同时被两个灯笼照亮的数目应尽可能的多 // // 思路是 // d[i][0]表示在节点i不放置灯笼所需的灯笼的最小值 // d[i][1]表示在节点i放置灯笼所

UVA - 10859 Placing Lampposts

As a part of the mission 'Beautification of Dhaka City', the government has decided to replace all the old lampposts with new expensive ones. Since the new ones are quite expensive and the budget is not up to the requirement, the government has decid

Placing Lampposts - UVa 10859 树形dp

As a part of the mission ?Beautification of Dhaka City?, the government has decided to replace all the old lampposts with new expensive ones. Since the new ones are quite expensive and the budget is not up to the requirement, the government has decid

LightOJ1230 Placing Lampposts(DP)

题目大概说给一个森林求其最小点覆盖数,同时在最小点覆盖条件下输出最多有多少条边被覆盖两次. dp[0/1][u]表示以u为根的子树内的边都被覆盖且u不属于/属于覆盖集所需的最少点数 另外,用cnt[0/1][u]表示满足dp[0/1][u]状态下子树内被覆盖两次最多的边数 对于dp[0][u]只能从其孩子结点v的dp[1][v]转移,而dp[1][u]从dp[0][v]或者dp[1][v]转移,转移时如果同时转移更新cnt的值.. 思路要清晰..转移细节要注意..另外注意是森林. 1 #incl

UVA 10859 Placing Lampposts 树形dp(水

题目链接:点击打开链接 题意: 白书P70 思路: 简单题,每个点分放或不放. import java.io.PrintWriter; import java.util.ArrayList; import java.util.Scanner; public class Main { int min(int a,int b){return a>b?b:a;} int max(int a,int b){return a>b?a:b;} static int N = 1005; static int

UVA 10859 Placing Lampposts(树DP)

题意:给一个n个顶点m条边的无向无环图,在尽量少的结点上放灯,使得所有边都被照亮.每盏灯将照亮以它为一个端点的所有边.在灯的总数最小的前提下,被两盏灯同时照亮的变数应该尽量大. 思路:无向无环图就是"森林",常用树形dp,本题要优化的目标有两个,放置的灯数a应尽量少,被两盏灯同时照亮的边数b应尽量大,为了统一,我们把b替换成"恰好被一盏灯照亮的边数c尽量小".然后设x=Ma+c为最终的优化目标,M是一个很大的正整数.当x取最小值的时候,x/M就是a的最小值,x%M就

UVa Placing Lampposts 树型DP

大致思路和大白书上的相同,不过感觉书上的决策部分讲解的并不是非常清楚,因此我在这里讲解一下我的决策思路. 首先,d(i,j)表示根节点为i的子树,当它的父节点为j(j=0或1)时的x的最小值(x的含义书上有讲解),要将该子树根节点和父节点相连的边的情况计算在内.接下来遍历森林中的每一棵树,对于每一棵树的根节点进行特别的处理,然后就对该树进行深度优先搜索dfs(i). 对于d[i][0]的情况,因为当前子树根节点i的父节点为0,所以该子树根节点的状态必为1,则d[i][0]=sum{d[k][1]

UVA 10859 Placing Lampposts 树形DP

dfs+记忆化搜索,白书上给了一种很神的存答案的方式,要同时保存两个值,可以将一个值乘以一个大整数加上另外一个. 具体状态转移见注释 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue>