UVALive 4527 Vaccination Centers 搜索+剪枝


Description

Download as PDF

To prepare for the flu pandemic, country E wants to set up some vaccination centers. There are n regions in the country, numbered 0, 1, 2,..., n - 1. The costs associated with the vaccination plan are the set up cost and the administration cost. The set up cost, namely ci, is the expense to build a vaccination center at region i, for i = 0 to n - 1. The administration cost mainly consists of the transportation cost for people to travel to nearby regions if no center established in their own region. It is certainly a difficult task to find out the set up costs and administration costs. Fortunately, the transportation bureau and the center for disease control have those numbers. Their investigation determined that the administration cost is a function of the distance from one region to the region where the closest vaccination center resides. More specifically, if there is no vaccination center in region i and region j is the nearest region of i with a vaccination center, the administration cost of region i would be the length of the shortest path from region i to region j. It is clear that the administration cost for a region with a vaccination center will be zero. Since E is famous for its efficiency, their transportation system connects all the regions. However, the structure of the road system is a tree. That is, there is only one route from one region to another. Now, the authority has decided that the number of vaccination centers must be smaller or equal to p. Once a set of regions V has been decided as the vaccination centers, the total set up cost will be the sum of the set up cost for each chosen region; the total administration cost will be the summation of the administration costs of all regions, and the total cost will be the sum of the total set up cost and the total administration cost. You are to write a program to select at most p vaccination centers so that the total cost is minimized.


Technical Specification

  1. 3$ \le$n$ \le$30.
  2. 0 < p$ \le$10.
  3. Let link(ij) be the distance between region i and region j that are directly connected with each other. 0 < link(ij)$ \le$100000 < ci$ \le$50000cilink(ij$ \in$N.

Input

There are several cases in the input file. The first line of each test case contains two integers np separated by a space; the following line contains n numbers corresponding to c0c1c2, ... cn-1 (the set up cost for the n regions numbered from 0 to n - 1). Each of the next n - 1lines contains three numbers separated by a space, the first two numbers of which indicate the identification numbers of two regions that are directly connected with each other, and the third number is the distance between these two regions. For example, ``0 1 3" denoteslink(0, 1) = 3.

Output

Output the total cost for each test case.



#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<iterator>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int mp[35][35];
int c[35];
int d[35];
int n,p;
int x,y,z;
int ans;
void dfs(int now,int pos,int d[],int cost,int cval)
{
    if(now>p||pos>=n||ans<=cval+c[pos]) return;
    int D[35];
    int t=cval+c[pos];
    for(int i=0;i<n;i++)
    {
        D[i]=min(d[i],mp[pos][i]);
        t+=D[i];
    }
    ans=min(ans,t);
    if(t<cost)                       //若选择当前点更优,则选择并继续dfs
    dfs(now+1,pos+1,D,t,cval+c[pos]);
    dfs(now,pos+1,d,cost,cval);
}
int main()
{
    while(~scanf("%d%d",&n,&p))
    {
        memset(mp,0x3f,sizeof(mp));
        for(int i=0;i<n;i++) scanf("%d",&c[i]),mp[i][i]=0;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            mp[x][y]=mp[y][x]=min(mp[x][y],z);
        }
        for(int k=0;k<n;k++)
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
        ans=0x7fffffff;
        memset(d,0x3f,sizeof(d));
        dfs(0,0,d,0x3f3f3f3f,0);
        printf("%d\n",ans);
    }
}


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TommyTT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值