BZOJ1444: [Jsoi2009]有趣的游戏(Trie图,矩乘)

Description

Input

注意 是0<=P, n , l, m≤ 10.

Output

Sample Input

input 1
3 2 2
1 2
1 2
AB
BA
AA
input 2
3 4 2
1 2
1 2
AABA
ABAA
BAAA

Sample Output

output 1
0.25
0.50
0.25

output 2
0.31
0.33
0.37

解题思路:

可以理解为Trie上倍增佛洛依德做矩乘累和。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 struct trnt{
  5     int ch[26];
  6     int fl;
  7     bool fin;
  8 }tr[111];
  9 class queue{
 10     public:
 11         queue(void){h=1,t=0;return ;}
 12         int nxt(int x){if(x+1>=999)return 1;return x+1;}
 13         void push(int x){t=nxt(t);line[t]=x;return ;}
 14         void pop(void){h=nxt(h);return ;}
 15         bool empty(void){return nxt(t)==h;}
 16         int front(void){return line[h];}
 17     private:
 18         int h,t,line[1000];
 19 }Q;
 20 int siz;
 21 int n,m,l;
 22 int ansp[111];
 23 char tmp[111];
 24 double lst[111];
 25 double ans[111];
 26 double martix[111][111];
 27 double temp[111][111];
 28 double pre[30];
 29 void Insert(char *a,int &plc)
 30 {
 31     int root=0;
 32     int len=l;
 33     for(int i=1;i<=len;i++)
 34     {
 35         int c=a[i]-'A';
 36         if(!tr[root].ch[c])
 37             tr[root].ch[c]=++siz;
 38         root=tr[root].ch[c];
 39     }
 40     tr[root].fin=true;
 41     plc=root;
 42     return ;
 43 }
 44 void Build(void)
 45 {
 46     int root=0;
 47     for(int i=0;i<m;i++)
 48         if(tr[root].ch[i])
 49             Q.push(tr[root].ch[i]);
 50     while(!Q.empty())
 51     {
 52         root=Q.front();
 53         Q.pop();
 54         for(int i=0;i<m;i++)
 55         {
 56             if(tr[root].ch[i])
 57             {
 58                 tr[tr[root].ch[i]].fl=tr[tr[root].fl].ch[i];
 59                 Q.push(tr[root].ch[i]);
 60             }else
 61                 tr[root].ch[i]=tr[tr[root].fl].ch[i];
 62         }
 63     }
 64     return ;
 65 }
 66 int main()
 67 {
 68     scanf("%d%d%d",&n,&l,&m);
 69     for(int i=0;i<m;i++)
 70     {
 71         int a,b;
 72         scanf("%d%d",&a,&b);
 73         pre[i]=(double)(a)/(double)(b);
 74     }
 75     for(int i=1;i<=n;i++)
 76     {
 77         scanf("%s",tmp+1);
 78         Insert(tmp,ansp[i]);
 79     }
 80     Build();
 81     for(int i=0;i<=siz;i++)
 82     {
 83         if(tr[i].fin)
 84         {
 85             martix[i][i]=1.00;
 86             continue;
 87         }
 88         for(int j=0;j<m;j++)
 89             martix[i][tr[i].ch[j]]+=pre[j];
 90         
 91     }
 92     int t=70;
 93     /*for(int i=0;i<=siz;i++)
 94     {
 95         for(int j=0;j<=siz;j++)
 96             printf("%.2lf ",martix[i][j]);
 97         puts("");
 98     }*/
 99     while(t--)
100     {
101         for(int i=0;i<=siz;i++)
102         {
103             for(int j=0;j<=siz;j++)
104             {
105                 temp[i][j]=0;
106                 for(int k=0;k<=siz;k++)
107                 {
108                     temp[i][j]+=martix[i][k]*martix[k][j];
109                 }
110             }
111         }
112         for(int i=0;i<=siz;i++)
113             for(int j=0;j<=siz;j++)
114                 martix[i][j]=temp[i][j];
115     }
116     for(int i=1;i<=n;i++)
117         printf("%.2lf
",martix[0][ansp[i]]);
118     return 0;
119 }
原文地址:https://www.cnblogs.com/blog-Dr-J/p/10014047.html