zoukankan      html  css  js  c++  java
  • B

    B - 小Y上学记——小Y的玩偶

    Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others)

    Problem Description

    小Y最喜欢拆拆拆了~尽管他不一定能装回去。

    小Y有一个很可爱的积木玩偶,是由一块一块积木拼接而成,现在小Y想把这个积木玩偶拆拆拆。

    每一块积木玩偶都有一个耐久值,想把一块积木拆出来,小Y需要付出的能量就是和它直接拼接的所有积木的耐久值之和。

    小Y很懒的~他想知道把这个玩偶全部拆好,最少需要付出多少能量?

    Input

    多组数据,每组数据首先是一个整数n表示积木块数。(0<n<=1000)

    接下来一行包含n个整数,表示每块积木的耐久值a[i](0<=a[i]<=100000)。

    接下来是n行,第i行代表第i块积木的连接情况。

    每一行首先是一个整数k,表示这块积木与k块积木相连,接下来是k个整数,代表与这块积木相连的积木标号(标号从0开始)

    保证连接情况合法。

    Output

    对于每组数据,输出一个整数,表示小Y需要的最少能量。

    Sample Input

    4
    10 20 30 40
    2 1 3
    2 0 2
    1 1
    1 0
    4
    100 100 100 100
    1 1
    3 0 2 3
    2 1 3
    2 1 2
    7
    40 10 20 10 20 80 40
    4 2 3 4 5
    1 4
    2 0 3
    5 0 2 4 5 6
    4 0 1 3 6
    2 0 3
    2 3 4
    

    Sample Output

    40
    400
    160

    Hint

    对于第一组数据,首先拆掉第2块积木,需要20能量,然后拆掉第1块积木,需要10能量,接着拆掉第3块积木,需要10能量,最后只剩下第0块了,不需要能量了。总共需要40点能量。

    对于第二组数据,无论怎么拆除,都是需要400点能量。

    解法:贪心+邻接表(矩阵也可以)

      每次拿走耐久度最大的点,更新图,在重复拿走,直到都成为独立的点即可。

      为何要拿走耐久度最大的点,假如这个点的耐久度为K,有m条边,每一条边的所连接的点的耐久度为Ki,如果不拿走这个点的话,需要拆了可连接他的m条边的点,则是需要消耗K*m能量,如果直接把这个点拆除了,则只是需要K1+K2+...+Km能量。

    因为,K*m>=K1+K2+...+Km,,细分下来,可以知道,每次拆除耐久度最大的点可以保证消耗的能量最小。再去更新连接图即可。

    代码:2015.7.31

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define MAX 100010
     6 using namespace std;
     7 int First[MAX];
     8 int SIGN;
     9 struct edge{int TO,Next,Vlaue;}ID[3*MAX];
    10 struct Node{int ID,V;}Poi[MAX];
    11 int cmp(Node a,Node b){return a.V>b.V;};
    12 void Add_E(int x,int y,int z)
    13 {
    14     ID[SIGN].TO=y;
    15     ID[SIGN].Vlaue=z;
    16     ID[SIGN].Next=First[x];
    17     First[x]=SIGN++;
    18 }
    19 void Add_E(int x,int y)
    20 {
    21     ID[SIGN].TO=y;
    22     ID[SIGN].Next=First[x];
    23     First[x]=SIGN++;
    24 }
    25 void Dele_x_y(int x,int y)/*删除x-y的边*/
    26 {
    27     int i,j;/*起始点要注意*/
    28     for(i=j=First[x];i!=0;j=i,i=ID[i].Next)
    29     {
    30         if(ID[i].TO==y)/*如果能够找到该边*/
    31         {
    32             if(i==j)First[x]=ID[i].Next;
    33             ID[j].Next=ID[i].Next;
    34             break;
    35         }
    36     }
    37     return ;
    38 }
    39 int GET_Sum(int x)/*查找与X相连的顶点*/
    40 {
    41     int i,Sum=0;
    42     for(i=First[x];i!=0;i=ID[i].Next)   //查找与该点相关的点
    43     {
    44         Sum+=ID[i].Vlaue;
    45         Dele_x_y(ID[i].TO,x);
    46     }
    47     return Sum;
    48 }
    49  
    50 int main()
    51 {
    52    int N,M,K,i,j,k;
    53    int x,y,z,Sum;
    54    int NUM[MAX];
    55    while(scanf("%d",&N)!=EOF)
    56    {
    57         SIGN=1;
    58         for(i=1;i<=N;i++)
    59         {
    60             scanf("%d",&NUM[i]);
    61             Poi[i].ID=i;
    62             Poi[i].V=NUM[i];
    63             First[i]=0;
    64         }
    65         sort(Poi+1,Poi+N+1,cmp);
    66         for(i=1;i<=N;i++)
    67         {
    68             scanf("%d",&K);
    69             while(K--)
    70             {
    71                 scanf("%d",&M);M+=1;
    72                 Add_E(i,M,NUM[M]);
    73             }
    74         }
    75         Sum=0;
    76         for(i=1;i<=N;i++)
    77         {
    78             Sum+=GET_Sum(Poi[i].ID);
    79         }
    80         printf("%d
    ",Sum);
    81    }
    82    return 0;
    83 }
    View Code
    转载请备注:
    **************************************
    * 作者: Wurq
    * 博客: https://www.cnblogs.com/Wurq/
    * Gitee: https://gitee.com/wurq
    **************************************
  • 相关阅读:
    JavaEE 第四周
    JavaEE 第三周
    JavaEE 第二周
    JavaEE 第一周
    js字符串方法
    javaee项目库存管理系统总结
    javaee期末团队项目库存管理系统概要信息
    JAVAEE第十一周
    JSON
    Facelets
  • 原文地址:https://www.cnblogs.com/Wurq/p/4692262.html
Copyright © 2011-2022 走看看