HDU - 3058 Generator AC自動機+高斯消元(未完待續)

題目鏈接點這裏

高斯消元精度爆炸,,卡不過去了,,

網上博客裏的代碼也都wa了,,先放着吧。。

#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin)
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define fuck(x) cout<<"q"<<endl;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<pair<int,int>,int> PIII;
typedef pair<int,int> PII;
const double eps=1e-12;
const int MX=111;
const int P=313;
int n,L,m;
struct Matrix
{
    double w[MX][MX];
    int n;
    void init(int x)
    {
        n=x;
        for(int i=0; i<n; i++)
            for(int j=0; j<=n; j++)w[i][j]=0;

    }
};
struct AC_trie
{
    int root,cnt;
    int End[500+10],to[500+10][26],fail[500+10];//改
    int newnode()
    {
        for(int i=0; i<L; i++) to[cnt][i]=-1;//改
        End[cnt]=0;
        return cnt++;
    }
    void init()
    {
        cnt=0;
        root=newnode();
    }
    int insert(char *s)
    {
        //cout<<cnt<<endl;
        int now=root;
        for(char *ss=s; *ss; ss++)
        {
            int v=*ss-'A';//改
            if(to[now][v]==-1)to[now][v]=newnode();
            now=to[now][v];
        }
        End[now]=1;//改
        return now;
    }
    void build()
    {
        queue<int> my;
        fail[root]=root;
        for(int i = 0; i < L; i++)//改
            if(to[root][i] == -1)
                to[root][i]= root;
            else
            {
                fail[to[root][i]]=root;
                my.push(to[root][i]);
            }
        while(!my.empty())
        {
            int u=my.front();
            my.pop();
            End[u]|=End[fail[u]];
            for(int i=0; i<L; i++)   //改
            {
                int v=to[u][i];
                if(v!=-1)
                {
                    fail[v]=to[fail[u]][i];
                    my.push(v);
                }
                else to[u][i]=to[fail[u]][i];
            }
        }
    }
    Matrix build_matrix()
    {
        Matrix ret;
        ret.init(cnt);
        for(int i=0; i<cnt; i++)
        {
            if(End[i]==0)
            {
                ret.w[i][i]=L;
                ret.w[i][cnt]=L;
                for(int j=0; j<L; j++)
                    ret.w[i][to[i][j]]+=-1;
            }
            else
            {
                ret.w[i][i]=1;
                ret.w[i][cnt]=0;
            }
        }
        return ret;
    }
} AC;
void print(double a[][MX],int n)
{
    for(int i=0; i<n; i++)
        for(int j=0; j<=n; j++)
            printf("%.2f%c",a[i][j],j==n?'\n':' ');
}
char s[MX];
int  gauss( double arr[][MX],int n)
{
    //print(arr,n);
    for(int i=0; i<n; i++)
    {
        int t=i;
        for(int j=i+1; j<n; j++) if(fabs(arr[j][i])>fabs(arr[t][i])) t=j;
        if(fabs(arr[t][i])<eps) continue;
        if(t!=i) for(int j=i; j<=n; j++) swap(arr[i][j],arr[t][j]);
        for(int j=i+1; j<n; j++) if(fabs(arr[j][i])>eps)
            {
                //double w=arr[j][i]/arr[i][i];
                //for(int k=i; k<=n; k++) arr[j][k]-=arr[i][k]*w;
                for(int k=i; k<=n; k++)arr[j][k]-=arr[i][k]/arr[i][i]*arr[j][i];
            }
    }

    for(int i=n-1; i>=0; i--)
        if(fabs(arr[i][i])>eps)
        {
            arr[i][n]/=arr[i][i];
            for(int j=i-1; j>=0; j--) arr[j][n]-=arr[j][i]*arr[i][n];
        }
    //print(arr,n);
    return 1;//唯一解
}
void gauss_eliminate( double arr[][MX],int n)
{
    int temp;
    double mmx;
    for(int i = 0; i < n; ++i)
    {
        temp = i;
        mmx = fabs(arr[i][i]);
        for(int j = i+1; j < n; ++j)
            if(fabs(arr[j][i]) > mmx)
            {
                mmx = fabs(arr[j][i]);
                temp = j;
            }
        if(temp != i) for(int j = 0; j <= n; ++j) swap(arr[temp][j],arr[i][j]);
        for(int j = n; j >= i; --j)
            for(int k = i+1; k < n;  ++k)
                arr[k][j] -= arr[k][i]/arr[i][i]*arr[i][j];

    }
    for(int i = n-1; i >= 0; --i)
    {
        for(int j = i+1; j < n; ++j)
            arr[i][n] -= arr[j][n]*arr[i][j];
        arr[i][n] /= arr[i][i];
    }
}
int main()
{
    FIN;
    //freopen("output1.txt","w",stdout);
    int _;
    int cas=0;
    scanf("%d",&_);
    while(_--)
    {
        scanf("%d%d",&L,&m);
        AC.init();
        for(int i=1; i<=m; i++)
        {
            scanf("%s",s);
            AC.insert(s);
        }
        AC.build();
        Matrix ret=AC.build_matrix();

        //cout<<AC.cnt<<endl;
        //print(ret.w,ret.n);

        gauss_eliminate(ret.w,ret.n);
        printf("%.2f\n",ret.w[0][ret.n]);
        //scanf("%s",s);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章