• hdu3247Resource Archiver(ac自动机+spfa)


    链接

    这题没想到怎么做,问了下p队长,大悟。。

    先求出任意两串的在trie树上的最短距离,期间是不能走到不合法的地方,我是用spfa求得,在更新和加入节点时判断一下是不是合法位置。

    求出最短距离之后,找出一条从0出发遍历所有串的最短距离,可以dp出,dp[i][j]表示当前状态以节点j串结尾的最短距离。

    枚举一下最后结尾的为哪一个串时距离最短。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 using namespace std;
     11 #define N 60010
     12 #define M 10010
     13 #define LL long long
     14 #define INF 0xfffffff
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 const int child_num = 2;
     19 int w[15][15];
     20 bool vis[N];
     21 int dis[N];
     22 class AC
     23 {
     24     private:
     25     int ch[N][child_num];
     26     int fail[N];
     27     int Q[N];
     28     int val[N],vv[N];
     29     int id[127];
     30     int sz ;
     31     int po[12];
     32     int dp[2110][12];
     33     public:
     34     void init()
     35     {
     36         fail[0] = 0;
     37         id['1'] = 1;
     38         id['0'] = 0;
     39     }
     40     void reset()
     41     {
     42         memset(ch[0],0,sizeof(ch[0]));
     43         memset(val,0,sizeof(val));
     44         memset(vv,0,sizeof(vv));
     45         sz=1;
     46     }
     47     void insert(char *a ,int key)
     48     {
     49         int p =0 ;
     50         for( ; *a ; a++)
     51         {
     52             int d = id[*a];
     53             if(ch[p][d]==0)
     54             {
     55                 memset(ch[sz],0,sizeof(ch[sz]));
     56                 ch[p][d] = sz++;
     57             }
     58             p = ch[p][d];
     59         }
     60         if(key!=-1)
     61         {
     62             val[p] = 1<<(key-1);
     63             po[key] = p;
     64         }
     65         else
     66         {
     67             vv[p] = 1;
     68         }
     69     }
     70     void construct()
     71     {
     72         int i,head=0,tail = 0;
     73         for(i = 0; i < child_num ; i++)
     74         if(ch[0][i])
     75         {
     76             fail[ch[0][i]] = 0;
     77             Q[tail++] = ch[0][i];
     78         }
     79         while(head!=tail)
     80         {
     81             int u = Q[head++];
     82             vv[u]|=vv[fail[u]];
     83             val[u]|=val[fail[u]];
     84             for(i = 0 ;i < child_num ; i++)
     85             {
     86                 if(ch[u][i])
     87                 {
     88                     fail[ch[u][i]] = ch[fail[u]][i];
     89                     Q[tail++] = ch[u][i];
     90                 }
     91                 else ch[u][i] = ch[fail[u]][i];
     92             }
     93         }
     94     }
     95     int spfa(int st,int ed)
     96     {
     97         int i;
     98         memset(vis,0,sizeof(vis));
     99         for(i = 0; i <= sz ;i++)
    100         dis[i] = INF;
    101         dis[st] = 0;
    102         vis[st] = 1;
    103         queue<int>q;
    104         q.push(st);
    105         while(!q.empty())
    106         {
    107             int u = q.front();
    108             q.pop();
    109             for(i = 0 ; i < child_num; i++)
    110             {
    111                 int v = ch[u][i];
    112                 if(vv[v]) continue;
    113                 dis[v] = min(dis[v],dis[u]+1);
    114                 //if(st == 4&&ed==8)
    115                 //cout<<v<<" "<<dis[v]<<" "<<u<<endl;
    116                 if(!vis[v])
    117                 {
    118                     vis[v] = 1;
    119                     q.push(v);
    120                 }
    121             }
    122         }
    123         return dis[ed];
    124     }
    125     void find_dis(int n)
    126     {
    127         int i,j;
    128         po[0] = 0;
    129         for(i = 1; i <= n ;i++)
    130         {
    131             w[0][i] = w[i][0] = spfa(0,po[i]);
    132             //cout<<w[0][i]<<endl;
    133         }
    134         for(i = 1; i <= n; i++)
    135             for(j = 1 ; j <= n ;j++)
    136             {
    137                 w[i][j] = spfa(po[i],po[j]);
    138                // cout<<w[i][j]<<" "<<i<<" "<<j<<endl;
    139             }
    140     }
    141     void work(int n)
    142     {
    143         int i,j,g;
    144         for(i = 0 ; i < (1<<n) ; i++)
    145             for(j = 0;j <= n; j++)
    146             dp[i][j] = INF;
    147         dp[0][0] = 0;
    148         for(i = 0 ;i < (1<<n) ; i++)
    149         {
    150             for(j = 0 ;j <= n ;j++)
    151             {
    152                 for(g = 0 ; g <= n ;g++)
    153                 {
    154                     if((1<<(g-1))&i) continue;
    155                     dp[i+(1<<(g-1))][g] = min(dp[i+(1<<(g-1))][g],dp[i][j]+w[j][g]);
    156                 }
    157             }
    158         }
    159         int ans = INF;
    160         for(i = 1 ; i <= n ; i++)
    161         ans = min(ans,dp[(1<<n)-1][i]);
    162         cout<<ans<<endl;
    163     }
    164 }ac;
    165 char vir[50010],re[1010];
    166 int main()
    167 {
    168     int n,m,i;
    169     ac.init();
    170     while(scanf("%d%d",&n,&m)&&n&&m)
    171     {
    172         ac.reset();
    173         for(i = 1; i <= n ;i++)
    174         {
    175             scanf("%s",re);
    176             ac.insert(re,i);
    177         }
    178         while(m--)
    179         {
    180             scanf("%s",vir);
    181             ac.insert(vir,-1);
    182         }
    183         ac.construct();
    184         ac.find_dis(n);
    185         ac.work(n);
    186     }
    187     return 0;
    188 }
    View Code
  • 相关阅读:
    模板层
    视图层
    路由层
    图书管理系统
    orm基础
    django目录结构介绍
    django基础
    20145211 《Java程序设计》第1周学习总结——小荷才露尖尖角
    实迷途其未远,觉今是而昨非——问卷调查
    20145203盖泽双问卷调查
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750817.html
Copyright © 2020-2023  润新知