zoukankan      html  css  js  c++  java
  • Resource Archiver HDU

    题意:

    给出n个资源串,m个病毒串,现在要如何连接资源串使得不含病毒串(可以重叠,样例就是重叠的)。

    题解:

    这题的套路和之前的很不同了,之前的AC自动机+DP的题目一般都是通过teir图去转移,

    这题有点小不同,认真分析这一题,我们可以知道n个资源串,m个病毒串在AC自动机的上面是哪一个节点

    所以可以根据teir图去处理出每一个资源串的节点不经过病毒串节点的最短距离,这个可以通过BFS实现。

    这个一开始要处理AC自动机上的root节点,毕竟是从root节点开始走的。

    处理出了每个点到其他点的最短距离之后,就变成了一个TSP问题,必须经过几个点的最短距离,状压写即可。

      1 #include <set>
      2 #include <map>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstring>
     11 #include <iostream>
     12 #include <algorithm>
     13 #include <unordered_map>
     14 
     15 #define  pi    acos(-1.0)
     16 #define  eps   1e-9
     17 #define  fi    first
     18 #define  se    second
     19 #define  rtl   rt<<1
     20 #define  rtr   rt<<1|1
     21 #define  bug                printf("******
    ")
     22 #define  mem(a, b)          memset(a,b,sizeof(a))
     23 #define  name2str(x)        #x
     24 #define  fuck(x)            cout<<#x" = "<<x<<endl
     25 #define  sfi(a)             scanf("%d", &a)
     26 #define  sffi(a, b)         scanf("%d %d", &a, &b)
     27 #define  sfffi(a, b, c)     scanf("%d %d %d", &a, &b, &c)
     28 #define  sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
     29 #define  sfL(a)             scanf("%lld", &a)
     30 #define  sffL(a, b)         scanf("%lld %lld", &a, &b)
     31 #define  sfffL(a, b, c)     scanf("%lld %lld %lld", &a, &b, &c)
     32 #define  sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
     33 #define  sfs(a)             scanf("%s", a)
     34 #define  sffs(a, b)         scanf("%s %s", a, b)
     35 #define  sfffs(a, b, c)     scanf("%s %s %s", a, b, c)
     36 #define  sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
     37 #define  FIN                freopen("../in.txt","r",stdin)
     38 #define  gcd(a, b)          __gcd(a,b)
     39 #define  lowbit(x)          x&-x
     40 #define  IO                 iOS::sync_with_stdio(false)
     41 
     42 
     43 using namespace std;
     44 typedef long long LL;
     45 typedef unsigned long long ULL;
     46 const ULL seed = 13331;
     47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
     48 const int maxn = 1e6 + 7;
     49 const int maxm = 8e6 + 10;
     50 const int INF = 0x3f3f3f3f;
     51 const int mod = 1e9 + 7;
     52 int n, m;
     53 char buf[maxn];
     54 
     55 struct Aho_Corasick {
     56     int next[60010][2], fail[60010], End[60010];
     57     int root, cnt;
     58 
     59     int newnode() {
     60         for (int i = 0; i < 2; i++) next[cnt][i] = -1;
     61         End[cnt++] = 0;
     62         return cnt - 1;
     63     }
     64 
     65     void init() {
     66         cnt = 0;
     67         root = newnode();
     68     }
     69 
     70     void insert(char buf[], int id) {
     71         int len = strlen(buf);
     72         int now = root;
     73         for (int i = 0; i < len; i++) {
     74             if (next[now][buf[i] - '0'] == -1) next[now][buf[i] - '0'] = newnode();
     75             now = next[now][buf[i] - '0'];
     76         }
     77         End[now] = id;
     78     }
     79 
     80     void build() {
     81         queue<int> Q;
     82         fail[root] = root;
     83         for (int i = 0; i < 2; i++)
     84             if (next[root][i] == -1) next[root][i] = root;
     85             else {
     86                 fail[next[root][i]] = root;
     87                 Q.push(next[root][i]);
     88             }
     89         while (!Q.empty()) {
     90             int now = Q.front();
     91             Q.pop();
     92             if (End[fail[now]] == -1) End[now] = -1;
     93             else End[now] |= End[fail[now]];
     94             for (int i = 0; i < 2; i++)
     95                 if (next[now][i] == -1) next[now][i] = next[fail[now]][i];
     96                 else {
     97                     fail[next[now][i]] = next[fail[now]][i];
     98                     Q.push(next[now][i]);
     99                 }
    100         }
    101     }
    102 
    103     int mp[15][15], dis[60010], pos[15], num, dp[15][1055];
    104 
    105     void bfs(int x) {
    106         mem(dis, -1);
    107         dis[pos[x]] = 0;
    108         queue<int> q;
    109         q.push(pos[x]);
    110         while (!q.empty()) {
    111             int now = q.front();
    112             q.pop();
    113             for (int i = 0; i < 2; ++i) {
    114                 int idx = next[now][i];
    115                 if (End[idx] == -1 || dis[idx] >= 0) continue;
    116                 dis[idx] = dis[now] + 1, q.push(idx);
    117             }
    118         }
    119         for (int i = 0; i < num; ++i) mp[x][i] = dis[pos[i]];
    120     }
    121 
    122     int solve() {
    123         pos[0] = 0, num = 1;
    124         for (int i = 0; i < cnt; ++i) if (End[i] > 0) pos[num++] = i;
    125         for (int i = 0; i < num; ++i) bfs(i);
    126 
    127 //        for (int i = 0; i < num; ++i) {
    128 //            for (int j = 0; j < num; ++j) {
    129 //                printf("%d ", mp[i][j]);
    130 //            }
    131 //            printf("
    ");
    132 //        }
    133 
    134 
    135         for (int i = 0; i < num; ++i)
    136             for (int j = 0; j < (1 << n); ++j)
    137                 dp[i][j] = INF;
    138         dp[0][0] = 0;
    139         for (int status = 0; status < (1 << n); ++status) {
    140             for (int i = 0; i < num; ++i) {
    141                 if (dp[i][status] == INF) continue;
    142                 for (int j = 0; j < num; ++j) {
    143                     if (mp[i][j] == -1 || (status | End[pos[j]]) == status) continue;
    144                     dp[j][status | End[pos[j]]] = min(dp[j][status | End[pos[j]]], dp[i][status] + mp[i][j]);
    145                 }
    146             }
    147         }
    148         int ans = INF;
    149         for (int i = 0; i < num; ++i) ans = min(ans, dp[i][(1 << n) - 1]);
    150         return ans;
    151     }
    152 
    153     void debug() {
    154         for (int i = 0; i < cnt; i++) {
    155             printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
    156             for (int j = 0; j < 26; j++) printf("%2d", next[i][j]);
    157             printf("]
    ");
    158         }
    159     }
    160 } ac;
    161 
    162 int main() {
    163    // FIN;
    164     while (~sffi(n, m)) {
    165         if (n == 0 && m == 0) break;
    166         ac.init();
    167         for (int i = 0; i < n; ++i) {
    168             sfs(buf);
    169             ac.insert(buf, (1 << i));
    170         }
    171         for (int i = 0; i < m; ++i) {
    172             sfs(buf);
    173             ac.insert(buf, -1);
    174         }
    175         ac.build();
    176         printf("%d
    ", ac.solve());
    177     }
    178     return 0;
    179 }
    View Code
  • 相关阅读:
    Spark的Shuffle机制
    Map Reduce的代码学习
    本地IDEA跑阿里云服务器Word Count
    HDFS的类学习和API基本操作
    本地IDEA(Windows)访问ECS服务器HBase
    本地IDEA访问ECS服务器HDFS
    阿里云ECS大数据环境搭建
    学会使用vue ui搭建项目
    用vue封装视频预览组件(手机端)
    项目中的部门使用级联选择器,编辑时初始化选中部门解决方案
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/11379564.html
Copyright © 2011-2022 走看看