zoukankan      html  css  js  c++  java
  • BZOJ4711 小奇挖矿

    Description

    【题目背景】
    小奇在喵星系使用了无限非概率驱动的采矿机,以至于在所有星球上都采出了一些矿石,现在它准备建一些矿石仓
    库并把矿石运到各个仓库里。
    【问题描述】
    喵星系有n个星球,标号为1到n,星球以及星球间的航线形成一棵树。所有星球间的双向航线的长度都为1。小奇要
    在若干个星球建矿石仓库,设立每个仓库的费用为K。对于未设立矿石仓库的星球,设其到一个仓库的距离为i,则
    将矿石运回的费用为Di。请你帮它决策最小化费用。

    Input

    第一行2个整数n,K。
    第二行n-1个整数,D1,D2,…Dn-1,保证Di<=Di+1。
    接下来n-1行,每行2个整数x,y,表示星球x和星球y存在双向航线。
    n<=200,0<=K,Di<=100000

    Output

    输出一行一个整数,表示最小费用。

    Sample Input

    8 10
    2 5 9 11 15 19 20
    1 4
    1 3
    1 7
    4 6
    2 8
    2 3
    3 5

    Sample Output

    38
    【样例解释】
    在1,2号星球建立仓库。
    令$f[i][j]$表示$i$的子树已经计算离$i$最近的仓库为$j$,且还没有算上建造的方案
    一个儿子有2种情况;
    1.最近的是k
    2.最近的是j
    写出来就是
    $f[x][i]=min(f[v][j]+k,f[v][i])$
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 using namespace std;
      7 struct Node
      8 {
      9   int next,to;
     10 }edge[200001];
     11 int num,head[21],cnt,tot,q[21],p[21],dep[21],fa[21],size[21],son[21],top[21];
     12 int dfn[21],n,k,d[21],ans,Min,sum,f[201][201],dis[201][201];
     13 void add(int u,int v)
     14 {
     15   num++;
     16   edge[num].next=head[u];
     17   head[u]=num;
     18   edge[num].to=v;
     19 }
     20 void dfs1(int x,int pa)
     21 {int i;
     22   dep[x]=dep[pa]+1;
     23   fa[x]=pa;
     24   size[x]=1;
     25   for (i=head[x];i;i=edge[i].next)
     26     {
     27       int v=edge[i].to;
     28       if (v==pa) continue;
     29       dfs1(v,x);
     30       size[x]+=size[v]; 
     31       if (size[v]>size[son[x]]) son[x]=v;
     32     } 
     33 }
     34 void dfs2(int x,int pa,int tp)
     35 {int i;
     36   top[x]=tp;
     37   dfn[x]=++tot;
     38   if (son[x]) dfs2(son[x],x,tp);
     39   for (i=head[x];i;i=edge[i].next)
     40     {
     41       int v=edge[i].to;
     42       if (v==pa||son[x]==v) continue;
     43       dfs2(v,x,v);
     44     }
     45 }
     46 int lca(int x,int y)
     47 {
     48   int as=0;
     49   while (top[x]!=top[y])
     50     {
     51       if (dep[top[x]]<dep[top[y]]) swap(x,y);
     52       x=fa[top[x]];
     53     }
     54   if (dep[x]>dep[y]) swap(x,y);
     55   return x;
     56 }
     57 int get_dis(int x,int y)
     58 {
     59   return dep[x]+dep[y]-2*dep[lca(x,y)];
     60 }
     61 void dfs(int x,int pa)
     62 {int i,j;
     63   for (i=1;i<=n;i++)
     64     f[x][i]=d[dis[x][i]];
     65   for (i=head[x];i;i=edge[i].next)
     66     {
     67       int v=edge[i].to;
     68       if (v==pa) continue;
     69       dfs(v,x);
     70       int as=2e9;
     71       for (j=1;j<=n;j++)
     72     as=min(as,f[v][j]+k);
     73       for (j=1;j<=n;j++)
     74     f[x][j]+=min(as,f[v][j]);
     75     }
     76 }
     77 int main()
     78 {int i,u,v,j;
     79   cin>>n>>k;
     80   for (i=1;i<=n-1;i++)
     81     {
     82       scanf("%d",&d[i]);
     83     }
     84   for (i=1;i<=n-1;i++)
     85     {
     86       scanf("%d%d",&u,&v);
     87       add(u,v);add(v,u);
     88     }
     89   dfs1(1,0);
     90   dfs2(1,0,1);
     91   for (i=1;i<=n;i++)
     92     {
     93       for (j=1;j<=n;j++)
     94     {
     95       dis[i][j]=get_dis(i,j);
     96     }
     97     }
     98   dfs(1,0);
     99   ans=2e9;
    100   for (i=1;i<=n;i++)
    101     ans=min(ans,f[1][i]+k);
    102   cout<<ans;
    103 }
  • 相关阅读:
    windows用户管理与远程管理
    Linux之基础网络配置
    linux之程序包管理
    linux之特殊权限
    设计模式学习笔记——Prototype原型模式
    设计模式学习笔记——Visitor 访问者模式
    XXX is not a function
    终于决定要开始写自己的博客了,先Mark一下
    element ui 与vue跨域通信操作 和框架语法,contentype
    跨域与版本控制
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8653194.html
Copyright © 2011-2022 走看看