zoukankan      html  css  js  c++  java
  • 荒诞

    【问题描述】
    我的灵魂与我之间的距离如此遥远,而我的存在却如此真实。
    ——加缪《局外人》
    我醒来的时候,发现满天星斗照在我的脸上。田野上的声音一直传到我的耳
    畔。夜的气味,土地的气味,海盐的气味,使我的两鬓感到清凉。这沉睡的夏夜
    的奇妙安静,像潮水一般浸透我的全身。这时,长夜将尽,汽笛叫了起来。它宣
    告有些人踏上旅途,要去一个从此和我无关痛痒的世界。
    这时我在想一个问题:我有一个 n 个点,m 条边的无向图,第 i 个点建立一
    个旅游站点的费用是 c_i。特别地,这张图中的任意两点间不存在节点数超过 10
    的简单路径。
    为了把一切都做得完善,为了使我感到不那么孤独,我想要建造一些旅游站
    点使得每个点要么建立了旅游站点,要么与它有边直接相连的点里至少有一个点
    建立了旅游站点。我还希望这个建造方案总花费尽量少。
    请求出这个花费。
    【输入格式】
    文件第一行有两个正整数 n 和 m。
    第二行包含 n 个整数,其中第 i 个数为 c_i,表示在第 i 个点建立旅游站点
    的费用。
    接下来 m 行,每行两个正整数 u,v,表示一条边(u,v),保证没有重边。
    【输出格式】
    输出只有一行,表示最小的总花费。
    【样例输入输出】
    absurdity.in
    6 6
    3 8 5 6 2 2
    1 2
    2 3
    1 3
    3 4
    4 5
    4 6
    absurdity.out
    7
    【数据范围】
    对于前 10%的测试点,满足所有的 c_i 相等。
    对于前 30%的测试点,满足 1<=n<=20,0<=m<=50。
    对于另外 15%的测试点,满足每个连通块都是一棵树。
    对于 100%的测试点,满足 1<=n<=2*10^4,0<=m<=2.5*10^4,0<=c_i<=10^4。

    很鬼的一道题

    两点之间路径点数不超过10,意味着联通块的DFS树深度<=10

    现在进行树形dp的唯一难点在于一个点会与祖先相互影响,于是考虑状压

    f[i][S]表示第i层(x号点)祖先状态为S的最小方案

    S是一个3进制数,0表示未选未覆盖,1表示已选,2表示未选被覆盖

    我们枚举x连向祖先的边,如果一个祖先状态为1,说明x可以不选

    f[i][S+2*pw[i-1]]=min(f[i-1][S])

    我们设S'为选x的状态,S'=S+pw[i-1]

    如果一个祖先状态为0,那么把它填成2:S'=S'+2*pw[j-1]

    于是我们又得到了选x的状态

    f[i][S']=min(f[i-1][S]+cost[x])

    因为还要考虑子孙对x的影响,所以还要在递归子树后转移

    f[i][S]=min(f[i+1][S+pw[i]],f[i+1][S+2*pw[i]])

    即子节点被控制

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct Node
     7 {
     8   int next,to;
     9 }edge[50001];
    10 int c[10001];
    11 int head[10001],num,n,fa[10001],dep[10001],f[2][60000],INF,pw[15],m,ans;
    12 bool vis[10001];
    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 dfs(int x)
    21 {int i;
    22   vis[x]=1;
    23   for (i=head[x];i;i=edge[i].next)
    24     {
    25       int v=edge[i].to;
    26       if (vis[v]==0)
    27     {
    28       fa[v]=x;
    29       dep[v]=dep[x]+1;
    30       dfs(v);
    31     }
    32     }
    33 }
    34 void dp(int x)
    35 {int i,j,s;
    36   bool link[11];
    37   int cur=dep[x]&1;
    38   memset(f[cur],127/2,sizeof(f[cur]));
    39   INF=f[cur][0];
    40   memset(link,0,sizeof(link));
    41   for (i=head[x];i;i=edge[i].next)
    42     {
    43       int v=edge[i].to;
    44       if (dep[v]<dep[x]) link[dep[v]-1]=1;
    45     }
    46   for (s=0;s<pw[dep[x]-1];s++)
    47     {
    48       if (f[cur^1][s]>=INF) continue;
    49       int ss=s+pw[dep[x]-1];
    50       bool flag=0;
    51       for (i=0;i<dep[x]-1;i++)
    52     if (link[i])
    53     {
    54       if (!(ss/pw[i]%3)) ss+=pw[i]*2;
    55       if ((s/pw[i]%3)==1) flag=1;
    56     }
    57       f[cur][ss]=min(f[cur][ss],f[cur^1][s]+c[x]);
    58       f[cur][s+flag*2*pw[dep[x]-1]]=min(f[cur][s+flag*2*pw[dep[x]-1]],f[cur^1][s]);
    59     }
    60   for (i=head[x];i;i=edge[i].next)
    61     {
    62       int v=edge[i].to;
    63       if (fa[v]==x)
    64     {
    65       dp(v);
    66       for (s=0;s<pw[dep[x]];s++)
    67         f[cur][s]=min(f[cur^1][s+pw[dep[x]]],f[cur^1][s+2*pw[dep[x]]]);
    68     }
    69     }
    70 }
    71 int main()
    72 {int i,u,v;
    73   cin>>n>>m;
    74   pw[0]=1;
    75   for (i=1;i<=10;i++)
    76     pw[i]=pw[i-1]*3;
    77   for (i=1;i<=n;i++)
    78     {
    79       scanf("%d",&c[i]);
    80     }
    81   for (i=1;i<=m;i++)
    82     {
    83       scanf("%d%d",&u,&v);
    84       add(u,v);add(v,u);
    85     }
    86   for (i=1;i<=n;i++)
    87     if (vis[i]==0)
    88     {
    89       dep[i]=1;
    90       dfs(i);
    91       f[0][0]=0;
    92       dp(i);
    93       ans+=min(f[1][1],f[1][2]);
    94       memset(f,127/2,sizeof(f));
    95     }
    96   cout<<ans;
    97 }
  • 相关阅读:
    PHP安全
    使用 jQuery 简化 Ajax 开发
    我的云之旅–HBase调试(139)
    Java的性能调优
    libsqlite3.dylib与libsqlite3.0.dylib区别
    zookeeper code
    最近的一个框架
    我的云之旅–Lucene内容存储进入Hadoop(136)
    Linux源码阅读推荐阅读图书
    我的云之旅–HMaster启动说明(140)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7794686.html
Copyright © 2011-2022 走看看