码迷,mamicode.com
首页 > 其他好文 > 详细

UVA - 10859 Placing Lampposts

时间:2017-08-30 23:41:37      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:quit   两种   iostream   ops   题解   ems   com   def   pre   

  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

 

题解:

  这个题目唯一巧妙的地方就是将最小化的目标两个变成了一个。首先我们可以考虑记使用灯数为a,记只有一盏灯照亮的边数为k,h为一个很大的常数,那么设x=h*a+k,那么显然就相当于记a为第一关键字,h为第二关键字,这样显然x越小,状态就越优秀,那么灯数就是x/h向下取整,k就是x%h。

  有了这个转化就十分好设状态了,设dp[i][0/1],表示当前位于i节点,父节点状态为j(j==0表示父节点没开灯,j==1表示开灯),保证以i为根的子树和i的父子边合法的最小x值。决策只有i节点放灯和不放两种,转移细节很多看代码吧。

 

代码:

#include<iostream>
#include<cstring>
#include<stdlib.h>
#include<stdio.h>
#include<algorithm>
#define MAXN 3010
using namespace std;
struct edge{
    int first;
    int next;
    int to;
}a[MAXN];
int dp[MAXN][2],b[MAXN][2];
int n,m,num,ans;

void cl(){
    memset(dp,0,sizeof(dp));
    memset(b,0,sizeof(b));
    memset(a,0,sizeof(a));
    num=0,ans=0;
}

void addedge(int from,int to){
    a[++num].to=to;
    a[num].next=a[from].first;
    a[from].first=num;
}

int dfs(int now,int have,int f){
    b[now][have]=1;
    int sum1=2000,sum2=1<<30;
    for(int i=a[now].first;i;i=a[i].next){
        int to=a[i].to;
        if(to==f) continue;
        sum1+=dfs(to,1,now);
    }
    if(!have&&f>=0) sum1++;
    if(have||f<0){
        sum2=0;
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            if(to==f) continue;
            sum2+=dfs(to,0,now); 
        }
        if(f>=0) sum2++;
    }
    dp[now][have]=min(sum1,sum2);
    return dp[now][have];
}

int main(){
    int t;scanf("%d",&t);
    while(t--){
        cl();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y;scanf("%d%d",&x,&y);
            addedge(x,y),addedge(y,x);
        }
        for(int i=0;i<n;i++){
            if(!b[i][0]) ans+=dfs(i,0,-1);
        }
        printf("%d %d %d\n",ans/2000,m-ans%2000,ans%2000);
    } 
}
 

 

UVA - 10859 Placing Lampposts

标签:quit   两种   iostream   ops   题解   ems   com   def   pre   

原文地址:http://www.cnblogs.com/renjianshige/p/7455673.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!