hdu4511 Historias de la serie Xiao Ming: la prueba de su novia [kuangbin topic-ac automata]

Esta pregunta requiere que expresemos la ruta como una cadena y luego construyamos el puntero de falla.
Cabe señalar que la posición inicial es el punto 1, que es ch [0] [0], no el nodo raíz. Por supuesto, si la ruta dada no contiene el punto uno, puede entenderse que comienza desde el nodo raíz.
La matriz dp contiene el camino más largo que debe tomarse.

#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#include <cstring>
#define fi first
#define se second
#define FIN freopen("in.txt","r",stdin)
#define FIO freopen("out.txt","w",stdout)
#define INF 0x3f3f3f3f
#define per(i,a,n) for(int i = a;i < n;i++)
#define rep(i,a,n) for(int i = n;i > a;i--)
#define pern(i,a,n) for(int i = a;i <= n;i++)
#define repn(i,a,n) for(int i = n;i >= a;i--)
#define fastio std::ios::sync_with_stdio(false)
#define all(a) a.begin(), a.end()
#define ll long long
#define pb push_back
#define endl "\n"
#define pii pair<int,int>
#define sc(n) scanf("%d", &n)
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
template<typename T> inline void _max(T &a,const T b){
    
    if(a<b) a = b;}
template<typename T> inline void _min(T &a,const T b){
    
    if(a>b) a = b;}
using namespace std;
//inline ll read(){
    
    
//    ll a=0;int f=0;char p=getchar();
//    while(!isdigit(p)){f|=p=='-';p=getchar();}
//    while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=getchar();}
//    return f?-a:a;
//}

const int maxn = 600;

const int maxnode = 60;
const double inf = 1e18;

int ch[maxn][maxnode]; //字典树
int cnt[maxn];    //单词出现次数
int sz;
int fail[maxn];
char s[10];
int n,m;
double dp[600][600];
double x[60],y[60];
double dis(int a,int b)
{
    
    
    double tmp=sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
    //cout << tmp << endl;
    return tmp;
}
void init()
{
    
    

    sz = 1;
    memset(ch[0], 0, sizeof(ch[0]));
    memset(cnt,0,sizeof(cnt));
    //memset(dp,INF,sizeof(dp));
    cnt[0] = 0;

}

void insert(char str[], int len) //插入字符串
{
    
    
    int u = 0;
    per(i, 0, len)
    {
    
    
        int v = str[i];
        if (!ch[u][v])
        {
    
    
            memset(ch[sz], 0, sizeof(ch[sz]));
            cnt[sz] = 0;
            ch[u][v] = sz++;
        }
        u = ch[u][v];
    }
    cnt[u] = 1;


    //在这里我们可以建立一个int-string的映射,以通过节点序号得知这个点是哪个单词的结尾
}

void getfail()
{
    
    
    //所有模式串已插入完成
    queue<int> q;
    pern(i, 1,n)
    {
    
    
        if (ch[0][i])
        {
    
    
            fail[ch[0][i]] = 0;
            q.push(ch[0][i]);
        }
    }
    while (!q.empty())
    {
    
    
        int now = q.front();
        q.pop();
        pern(i, 1, n)
        {
    
    
            if (ch[now][i])
            {
    
    
                fail[ch[now][i]] = ch[fail[now]][i];
                q.push(ch[now][i]);
            }
            else
                ch[now][i] = ch[fail[now]][i];
        }
        cnt[now] |= cnt[fail[now]];
    }
}
void solve()
{
    
    
    for(int i=1;i<=n;i++)
        for(int j=0;j<sz;j++)
            dp[i][j]=inf;
    dp[1][ch[0][1]] = 0;
    pern(i,1,n)
    {
    
    
        per(j,0,sz)
        {
    
    
            if(dp[i][j]<inf)
            {
    
    
                pern(k,i+1,n)
                {
    
    
                    if(cnt[ch[j][k]] == 0)
                    {
    
    
                        dp[k][ch[j][k]] = min(dp[k][ch[j][k]],dp[i][j]+dis(i,k));
                    }
                }
            }
        }
    }
    double ans = inf;
    per(i,0,sz) ans = min(ans,dp[n][i]);
    if(ans >= inf)
        printf("Can not be reached!\n");
    else
        printf("%.2lf\n",ans);
}
int main()
{
    
    

    #ifndef ONLINE_JUDGE
        int startTime = clock();
        FIN;
    #endif
    //fastio;
	//忘记初始化是小狗
    //freopen("out.txt","w",stdout);
    //ios::sync_with_stdio(false);
    int k = 0,t;
    while(~scanf("%d%d",&n,&m))
    {
    
    
        if(n+m == 0) return 0;
        init();
        pern(i,1,n)
        {
    
    
            scanf("%lf%lf",&x[i],&y[i]);
        }
        per(i,0,m)
        {
    
    
            sc(k);
            per(j,0,k)
            {
    
    
                sc(t);
                s[j] = t;
            }
            s[k] = '\0';
            insert(s,k);
        }
        getfail();
        solve();
    }
    #ifndef ONLINE_JUDGE
        printf("\nTime = %dms\n", clock() - startTime);
    #endif
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_39586345/article/details/108569095
Recomendado
Clasificación