• NKOJ1472 警卫安排


    P1472警卫安排

     
    时间限制 : 10000 MS   空间限制 : 65536 KB
    问题描述

    一个重要的基地被分为n个连通的区域。出于某种神秘的原因,这些区域以一个区域为核心,呈一颗树形分布。
    在每个区域安排警卫所需要的费用是不同的,而每个区域的警卫都可以望见其相邻的区域,只要一个区域被一个警卫望见或者是安排有警卫,这个区域就是安全的。你的任务是:在确保所有区域都是安全的情况下,找到安排警卫的最小费用。

    输入格式

    第一行n,表示树中结点的数目。
    接下来的n行描述了n个区域的信息,每一行包含的整数依次为:区域的标号i(0<i<=n),在区域i安排警卫的费用k,区域i的子结点数目m,接下来m个数为区域i的子结点编号。

    输出格式

    一行一个整数,为最小的安排费用。

    样例输入

    6
    1 30 3 2 3 4
    2 16 2 5 6
    3 5 0
    4 4 0
    5 11 0
    6 5 0

    样例输出

    25

    提示

    对于所有的数据,0<n<=720。

     
    【题解】
    ——by 朱全民
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cmath> 
      6 #include <algorithm>
      7 #define min(a, b) ((a) < (b) ? (a) : (b))
      8 #define max(a, b) ((a) > (b) ? (a) : (b))
      9 
     10 inline void read(int &x)
     11 {
     12     x = 0;char ch = getchar(), c = ch;
     13     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     14     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     15     if(c == '-')x = -x;
     16 }
     17 
     18 const int INF = 0x3f3f3f3f; 
     19 const int MAXN = 800 + 10;
     20 
     21 int n,cost[MAXN];
     22 
     23 struct Edge
     24 {
     25     int u,v,next;
     26     Edge(int _u, int _v, int _next){u = _u;v = _v;next = _next;}
     27     Edge(){}
     28 }edge[MAXN << 1];
     29 
     30 int head[MAXN],cnt;
     31 
     32 inline void insert(int a, int b)
     33 {
     34     edge[++cnt] = Edge(a,b,head[a]);
     35     head[a] = cnt;
     36 }
     37 
     38 int fa[MAXN], dp[MAXN][3];
     39 /*
     40 dp[i][0]表示i放警卫的最小费用 
     41 dp[i][1]表示i被儿子看到的最小费用
     42 dp[i][2]表示i被父亲看到的最小费用 
     43 
     44 dp[i][0] = Σmin(dp[son[i]][2], dp[son[i]][0],dp[son[i][1]) + cost[i]
     45 dp[i][1] = Σmin(dp[son[i]][0], dp[son[i]][1]) + dp[j][0] j从son[i]中除去
     46 dp[i][2] = Σmin(dp[son[i]][1], dp[son[i]][2]) 
     47 */
     48 
     49 void dfs(int u)
     50 {
     51     if(!u)return;
     52     register int num = 0, v, cnt, tmp;//先更新0 2 
     53     for(register int pos = head[u];pos;pos = edge[pos].next)
     54     {
     55         v = edge[pos].v;
     56         if(v == fa[u])continue;
     57         fa[v] = u;
     58         ++ num;
     59         dfs(v);
     60         dp[u][0] += min(dp[v][2], min(dp[v][0], dp[v][1]));
     61         dp[u][2] += min(dp[v][1], dp[v][0]);        
     62     } 
     63     if(!num)
     64     {
     65         dp[u][0] = cost[u];
     66         dp[u][1] = INF;
     67         dp[u][2] = 0;
     68         return;
     69     }
     70     dp[u][0] += cost[u]; 
     71     dp[u][1] = INF;
     72     for(register int i = 1;i <= num;++ i)
     73     {
     74         cnt = 1;
     75         tmp = 0;
     76         for(register int pos = head[u];pos;pos = edge[pos].next, ++ cnt)
     77         {
     78             v = edge[pos].v;
     79             if(v == fa[u])
     80             {
     81                 -- cnt;
     82                 continue; 
     83             }
     84             if(cnt == i)tmp += dp[v][0];
     85             else tmp += min(dp[v][0], dp[v][1]); 
     86         }
     87         dp[u][1] = min(dp[u][1], tmp);
     88     }
     89 }
     90 
     91 int main()
     92 {
     93     read(n);
     94     register int root, tmp1,tmp2;
     95     for(register int i = 1;i <= n;++ i)
     96     {
     97         read(root),read(cost[root]),read(tmp1);
     98         for(register int j = 1;j <= tmp1;++ j)
     99         {
    100             read(tmp2);
    101             insert(root, tmp2),insert(tmp2, root);
    102         }
    103     }
    104     dfs(root);
    105     printf("%d", min(dp[root][0], dp[root][1]));
    106     return 0;
    107 }
    NKOJ
     
  • 相关阅读:
    优先队列总结
    CodeForces 567D One-Dimensional Battle Ships
    CodeForces 567D One-Dimensional Battle Ships
    codeforces 1016B. Segment Occurrences
    codeforces 1016B. Segment Occurrences
    poj3249(求最长路)
    poj3249(求最长路)
    poj 2186
    2017年第八蓝桥杯C/C++ A组国赛 —— 第二题:生命游戏
    Fence Repair POJ
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7503139.html
Copyright © 2020-2023  润新知