【HDU】3247 Resource Archiver

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<queue>

  4 #define MAXN 60000

  5 #define MAXL (1<<10)

  6 #define MAXM 200

  7 using namespace std;

  8 struct Trie {

  9     bool virus;

 10     int end, fail, next[2];

 11     void Init() {

 12         virus = false;

 13         end = fail = next[0] = next[1] = 0;

 14     }

 15 };

 16 Trie tree[MAXN];

 17 char str[MAXN];

 18 int size, cnt;

 19 int pos[MAXM], dis[MAXN], G[MAXM][MAXM], dp[MAXL][MAXM];

 20 void Insert(char *s, int id) {

 21     int now, t;

 22     for (now = 0; *s; s++) {

 23         t = *s - '0';

 24         if (!tree[now].next[t]) {

 25             tree[++size].Init();

 26             tree[now].next[t] = size;

 27         }

 28         now = tree[now].next[t];

 29     }

 30     if (id >= 0)

 31         tree[now].end = 1 << id;

 32     else

 33         tree[now].virus = true;

 34 }

 35 void BFS() {

 36     int now, i, p;

 37     queue<int> q;

 38     q.push(0);

 39     while (!q.empty()) {

 40         now = q.front();

 41         q.pop();

 42         for (i = 0; i < 2; i++) {

 43             if (tree[now].next[i]) {

 44                 p = tree[now].next[i];

 45                 q.push(p);

 46                 if (now)

 47                     tree[p].fail = tree[tree[now].fail].next[i];

 48                 tree[p].end |= tree[tree[p].fail].end;

 49                 tree[p].virus |= tree[tree[p].fail].virus;

 50             } else

 51                 tree[now].next[i] = tree[tree[now].fail].next[i];

 52         }

 53     }

 54 }

 55 void Path(int k) {

 56     int now, i, p;

 57     queue<int> q;

 58     q.push(pos[k]);

 59     memset(dis, -1, sizeof(dis));

 60     dis[pos[k]] = 0;

 61     while (!q.empty()) {

 62         now = q.front();

 63         q.pop();

 64         for (i = 0; i < 2; i++) {

 65             p = tree[now].next[i];

 66             if (dis[p] < 0 && !tree[p].virus) {

 67                 dis[p] = dis[now] + 1;

 68                 q.push(p);

 69             }

 70         }

 71     }

 72     for (i = 0; i < cnt; i++)

 73         G[k][i] = dis[pos[i]];

 74 }

 75 inline int MIN(int x, int y) {

 76     if (x < 0 || y < 0)

 77         return x > y ? x : y;

 78     return x > y ? y : x;

 79 }

 80 void DoIt(int n) {

 81     int i, j, k, t, ans;

 82     memset(dp, -1, sizeof(dp));

 83     dp[0][0] = 0;

 84     for (i = 0; i < (1 << n); i++) {

 85         for (j = 0; j < cnt; j++) {

 86             if (dp[i][j] < 0)

 87                 continue;

 88             for (k = 0; k < cnt; k++) {

 89                 if (G[j][k] < 0)

 90                     continue;

 91                 t = i | tree[pos[k]].end;

 92                 dp[t][k] = MIN(dp[t][k], dp[i][j] + G[j][k]);

 93             }

 94         }

 95     }

 96     t = (1 << n) - 1;

 97     for (ans = -1, i = 0; i < cnt; i++)

 98         ans = MIN(ans, dp[t][i]);

 99     printf("%d\n", ans);

100 }

101 int main() {

102     int n, m, i;

103     while (scanf("%d%d", &n, &m), n) {

104         tree[0].Init();

105         for (size = i = 0; i < n; i++) {

106             scanf(" %s", str);

107             Insert(str, i);

108         }

109         while (m--) {

110             scanf(" %s", str);

111             Insert(str, -1);

112         }

113         BFS();

114         pos[0] = 0;

115         for (cnt = 1, i = 0; i <= size; i++) {

116             if (tree[i].end)

117                 pos[cnt++] = i;

118         }

119         for (i = 0; i < cnt; i++)

120             Path(i);

121         DoIt(n);

122     }

123     return 0;

124 }

你可能感兴趣的:(resource)