• 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 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

    题意:

      一个无向图上,要去放灯,要求每条边都被照亮的最少灯数,并且1边被两盏灯照亮的边数要尽量多,输出灯数,两盏照亮的边数,一盏照亮的边数。

    题解:

      首先对于每个节点,我们都有取或不取,这个DP就好了,下面是如何保证取优先值方法

    取双优值方法:

          考虑要保证a最小的情况下...b最小...那么就是在状态转移过程中保证a是占主体地位的..只有当a相等时..b才发挥作用...这可以联想到两个数比较.

          首先要比最高位..当最高位不相等时..低位如何变换都不能影响到比较结果...

                     那么选取一个尽可能大但又不至于爆int,long long的数M..让在题目范围内..b如何多..都达不到M..那么表示状态下值为a*M+b

                     输出答案时...P/M为第一个最优的...P%M为保证第一个最优下第二个最优

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N = 1e3+20, M = 30005, mod = 1e9+7, inf = 0x3f3f3f3f;
    typedef long long ll;
    //不同为1,相同为0
    vector<int > G[N];
    int n,m,vis[N],T,ans,dp[N][2];
    void dfs(int u) {
        dp[u][0] = 0;
        dp[u][1] = M+1;
        vis[u] = 1;
        for(int i=0;i<G[u].size();i++) {
            int to = G[u][i];
            if(vis[to]) continue;
            dfs(to);
            dp[u][0]+=dp[to][1];
            dp[u][1] += min(dp[to][1]-1,dp[to][0]+1);
        }
    }
    int main() {
        scanf("%d",&T);
        while(T--) {
            for(int i=0;i<N;i++) G[i].clear(), vis[i] = 0;
            scanf("%d%d",&n,&m);
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=m;i++) {
                int a,b;
                scanf("%d%d",&a,&b);
                a++,b++;
                G[a].push_back(b);
                G[b].push_back(a);
            }
            ans = 0;
            for(int i=1;i<=n;i++) {
                if(vis[i]) continue;
                dfs(i);
               dp[i][1]--;
                ans += min(dp[i][0], dp[i][1]);
               // cout<<min(dp[i][0], dp[i][1])<<endl;
            }
            printf("%d %d %d
    ",ans/M, m-ans%M, ans%M);
        }
        return 0;
    }
  • 相关阅读:
    可视化开发_AppInventor2似乎被抛弃了
    PHP内核学习(一)SAPI
    代码整洁之道(一)理论篇
    Silence.js高效开发移动Web前端类库
    梦游前端,JavaScript兼容性
    20分钟入门正则表达式
    原生Javascript 省市区下拉列表插件
    Tortoise-SVN 出现“unable to connect to a repository at url no element found”解决办法
    PHP实现好友生日邮件提醒
    第一份工作
  • 原文地址:https://www.cnblogs.com/zxhl/p/5352475.html
Copyright © 2020-2023  润新知