zoukankan      html  css  js  c++  java
  • Uva 10859 Placing Lampposts 树形dp

    Input: Standard In
    Output: Standard Out

    Next Generation Contest 1 

    Time Limit: 2 seconds

    Problem D
    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 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 integersa 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

    Problem Setter: Sohel Hafiz.
    Special thanks to Per Austrin.

    -------------

    pair<int,int> 表示放置的灯数,恰好被一盏灯照亮的边数

    f[i][0]表示节点i的父节点不放灯的情况,i及其子节点的最小值

    f[i][1]表示节点i的父节点放灯的情况,i及其子节点的最小值

    ① 节点i放灯

    灯数+1

    此时f[i,j]=sum{ f[k,1] | k是i的子节点 }

    若父节点不放灯,且i不是根节点。恰好被一盏灯照亮的边数+1 (i与父节点之间的边)

    ②节点i不放灯

    必须是i的父节点放灯或i为根节点。

    此时f[i,j]=sum{ f[k,0] | k是i的子节点 }

    若i节点不是根节点,则恰好被一盏灯照亮的边数+1 (i与父节点之间的边)

    -------------

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define PR pair<int,int>
    
    using namespace std;
    
    //const
    const int maxn=1111;
    const int maxm=11111;
    
    //Tree
    struct EDGENODE{
        int to;
        int next;
    }edges[maxm];
    int edge;
    int head[maxn];
    void addedge(int u,int v){
        edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        edges[edge].to=u,edges[edge].next=head[v],head[v]=edge++;
    }
    void init(){
        memset(head,-1,sizeof(head));
        edge=0;
    }
    
    //------
    int n,m;
    bool vis[maxn][2];
    PR f[maxn][2];
    
    //dfs()
    PR dfs(int x,int y,int pa)
    {
        if (vis[x][y]) return f[x][y];
        PR ret=make_pair(0,0),ret0=make_pair(0,0),tmp;
        //----放置
        ret.first+=1;
        for (int k=head[x];k!=-1;k=edges[k].next)
        {
            int v=edges[k].to;
            if (v!=pa)
            {
                tmp=dfs(v,1,x);
                ret.first+=tmp.first;
                ret.second+=tmp.second;
            }
        }
        if (y==0&&pa!=-1) ret.second+=1;
        //----不放置
        if (y==1||pa==-1)
        {
            for (int k=head[x];k!=-1;k=edges[k].next)
            {
                int v=edges[k].to;
                if (v!=pa)
                {
                    tmp=dfs(v,0,x);
                    ret0.first+=tmp.first;
                    ret0.second+=tmp.second;
                }
            }
            if (pa!=-1) ret0.second+=1;
            ret=min(ret,ret0);
        }
        //----
        vis[x][y]=true;
        f[x][y]=ret;
        return ret;
    }
    
    int main()
    {
        int T;
        PR tmp,ans;
        scanf("%d",&T);
        while (T--)
        {
            init();
            memset(f,0,sizeof(f));
            memset(vis,0,sizeof(vis));
            scanf("%d%d",&n,&m);
            for (int i=0;i<m;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                addedge(a,b);
            }
            ans=make_pair(0,0);
            for (int i=0;i<n;i++)
            {
                if (!vis[i][0])
                {
                    tmp=dfs(i,0,-1);
                    ans.first+=tmp.first;
                    ans.second+=tmp.second;
                }
            }
            printf("%d %d %d\n",ans.first,m-ans.second,ans.second);
        }
        return 0;
    }
    








  • 相关阅读:
    如何上架一个iOS APP(2020年最新版教程)
    可以在Windows申请iOS证书上架iOS APP---Appuploader
    上传了ipa但iTunes Connect没有构建版本问题
    iOS证书类型介绍及申请教程
    APP专用密码app-specific password怎么设置
    Windows电脑申请iOS证书教程及工具分享
    【2020】申请iOS个人开发者账号流程
    【分享】使用免费的苹果开发者账号申请iOS证书打包测试教程
    iOS证书及描述文件制作流程详解
    linux /bin/bash^M: bad interpreter的解决办法
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226361.html
Copyright © 2011-2022 走看看