Placing Lampposts - UVa 10859 树形dp

本文探讨了Dhakacity城市照明优化问题,通过构建无环图模型,利用树形动态规划算法,寻找最少路灯数量及最大化双路灯覆盖道路数量的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 decided to buy the minimum number of lampposts required to light the whole city.

Dhaka city can be modeled as an undirected graph with no cycles, multi-edges or loops. There are several roads and junctions. A lamppost can only be placed on junctions. These lampposts can emit light in all the directions, and that means a lamppost that is placed in a junction will light all the roads leading away from it.

The �Dhaka City Corporation� has given you the road map of Dhaka city. You are hired to find the minimum number of lampposts that will be required to light the whole city. These lampposts can then be placed on the required junctions to provide the service. There could be many combinations of placing these lampposts that will cover all the roads. In that case, you have to place them in such a way that the number of roads receiving light from two lampposts is maximized.

Input

There will be several cases in the input file. The first line of input will contain an integer T(T<=30) that will determine the number of test cases. Each case will start with two integers N(N<=1000) and M( M<N) that will indicate the number of junctions and roads respectively. The junctions are numbered from 0 to N-1. Each of the next M lines will contain two integers a and b, which implies there is a road from junction a to b,
( 0<= a,b < N ) and a != b. There is a blank line separating two consecutive input sets.

Output

For each line of input, there will be one line of output. Each output line will contain 3 integers, with one space separating two consecutive numbers. The first of these integers will indicate the minimum number of lampposts required to light the whole city. The second integer will be the number of roads that are receiving lights from two lampposts and the third integer will be the number of roads that are receiving light from only one lamppost.

Sample Input

2
4 3
0 1
1 2
2 3

5 4
0 1
0 2
0 3
0 4

Sample Output

2 1 2
1 0 4

题意:有n个点和m条街,每个点上可以装一个路灯,每条街都必须在两端至少有一个灯,问至少需要多少个灯,如果灯数相同的情况下,最多有多少条街可以在两端都有路灯。

思路:简单的树形dp,就是本题可能不止是一棵树。dp[u][0 1][k]表示在u节点不安装/安装路灯的情况,dp[u][k][0 1]表示u节点及其以下的街都满足要求是最少的路灯数和最大的两端都有灯的街数。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int n,m,dp[1010][2][2],vis[1010];
vector<int> vc[1010];
void dfs(int u,int f)
{
    vis[u]=1;
    dp[u][1][0]=1;
    int i,j,k,len=vc[u].size(),v;
    for(i=0;i<len;i++)
    {
        v=vc[u][i];
        if(v==f)
          continue;
        dfs(v,u);
        dp[u][0][0]+=dp[v][1][0];
        dp[u][0][1]+=dp[v][1][1];

        if(dp[v][0][0]<dp[v][1][0])
        {
            dp[u][1][0]+=dp[v][0][0];
            dp[u][1][1]+=dp[v][0][1];
        }
        else if(dp[v][0][0]>dp[v][1][0])
        {
            dp[u][1][0]+=dp[v][1][0];
            dp[u][1][1]+=dp[v][1][1]+1;
        }
        else
        {
            dp[u][1][0]+=dp[v][0][0];
            dp[u][1][1]+=max(dp[v][0][1],dp[v][1][1]+1);
        }
    }
}
int main()
{
    int T,t,i,j,k,u,v,a,b,c;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
           vc[i].clear();
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            vc[u].push_back(v);
            vc[v].push_back(u);
        }
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        a=0;b=0;c=0;
        for(i=0;i<n;i++)
           if(vis[i]==0)
           {
               dfs(i,-1);
               if(dp[i][0][0]<dp[i][1][0])
                 a+=dp[i][0][0],b+=dp[i][0][1];
               else if(dp[i][0][0]>dp[i][1][0])
                 a+=dp[i][1][0],b+=dp[i][1][1];
               else
                 a+=dp[i][0][0],b+=max(dp[i][0][1],dp[i][1][1]);
            }
        printf("%d %d %d\n",a,b,m-b);
    }
}



标题基于SpringBoot和Vue的养老院系统设计与实现AI更换标题第1章引言介绍养老院系统的研究背景、意义,以及基于SpringBoot和Vue技术选型的原因。1.1研究背景与意义分析当前养老院信息化管理的需求,阐述本系统的实际意义。1.2国内外研究现状概述养老院信息系统的国内外发展现状与趋势。1.3论文方法与创新点介绍本文的设计思路、实现方法和创新之处。第2章相关技术概述简要介绍SpringBoot和Vue的技术特点和在养老院系统中的应用。2.1SpringBoot技术阐述SpringBoot框架的核心特性和优势。2.2Vue技术介绍Vue框架的基本原理及在前端开发中的应用。2.3技术选型分析分析选用SpringBoot和Vue进行养老院系统开发的合理性。第3章系统需求分析详细分析养老院系统的功能需求和性能需求。3.1用户需求调研介绍对养老院工作人员和老人的需求调研结果。3.2功能需求分析列举并解释系统的核心功能需求。3.3性能需求分析明确系统应满足的性能指标,如响应时间、并发用户数等。第4章系统设计详细介绍养老院系统的架构设计、数据库设计和界面设计。4.1架构设计给出系统的整体架构图,解释各模块之间的关系。4.2数据库设计阐述数据库表结构、关系和索引等设计细节。4.3界面设计展示系统的主要界面设计,包括色彩、布局和交互元素。第5章系统实现详细描述系统的实现过程,包括前后端代码编写、测试和部署等。5.1前端实现介绍基于Vue的前端页面实现细节。5.2后端实现阐述基于SpringBoot的后端服务实现过程。5.3系统测试与部署说明系统的测试方法、测试结果及部署环境。第6章系统评价与展望对养老院系统进行综合评价,并提出改进和扩展方向。6.1系统评价从功能、性能和用户体验等方面评价系统的实际效果。6.2未来工作展望根据系统评价结果,提出未来优化和扩展的建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值