• hdu 4511 小明系列故事——女友的考验(AC自动机+dp)


    题目链接:hdu 4511 小明系列故事——女友的考验

    题意:

    中文不解释。

    题解:

    考虑将那些限制的条件插进AC自动机里面,然后在AC自动机上dp一下最短路就行了。

    考虑dp[i][j]表示当前在第i个点上,在AC自动机的第j个点上的最短路。

    然后dp转移看代码。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 using namespace std;
     4 typedef pair<double,double>P;
     5 const int AC_N=1000,tyn=50;
     6 int n,m,s[50];
     7 P a[60];
     8 double dp[55][505],inf=1e18;
     9 
    10 struct AC_automation{
    11     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
    12     void nw(){cnt[++tot]=0,fail[tot]=0;memset(tr[tot],0,sizeof(tr[tot]));}
    13     void init(){tot=-1,fail[0]=-1,nw();}
    14     void insert(int *s,int x=0){
    15         for(int i=0,w;s[i];x=tr[x][w],i++)
    16             if(!tr[x][w=s[i]])nw(),tr[x][w]=tot;
    17         cnt[x]++;
    18     }
    19     void build(int head=1,int tail=0){
    20         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
    21         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
    22             if(tr[x][i])
    23             {
    24                 fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
    25                 cnt[tr[x][i]]+=cnt[tr[fail[x]][i]];
    26             }
    27             else tr[x][i]=tr[fail[x]][i];
    28     }
    29     double dis(P &a,P &b)
    30     {
    31         return sqrt((a.first-b.first)*(a.first-b.first)
    32               +(a.second-b.second)*(a.second-b.second));
    33     }
    34     void solve()
    35     {
    36         F(i,0,n)F(j,0,tot)dp[i][j]=inf;
    37         dp[1][tr[0][1]]=0;
    38         F(i,1,n-1)F(j,0,tot)if(dp[i][j]!=inf)
    39         {
    40             F(k,i+1,n)
    41             {
    42                 int nxt=tr[j][k];
    43                 if(cnt[nxt])continue;
    44                 dp[k][nxt]=min(dp[k][nxt],dp[i][j]+dis(a[i],a[k]));
    45             }
    46         }
    47         double ans=inf;
    48         F(j,0,tot)ans=min(ans,dp[n][j]);
    49         if(ans==inf)puts("Can not be reached!");
    50         else printf("%.2f
    ",ans);
    51     }
    52 }AC;
    53 
    54 int main()
    55 {
    56     while(scanf("%d%d",&n,&m),n+m)
    57     {
    58         F(i,1,n)scanf("%lf%lf",&a[i].first,&a[i].second);
    59         AC.init();
    60         F(i,1,m)
    61         {
    62             memset(s,0,sizeof(s));
    63             int num,x;
    64             scanf("%d",&num);
    65             F(j,1,num)scanf("%d",s+j-1);
    66             AC.insert(s);
    67         }
    68         AC.build(),AC.solve();
    69     }
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    SVN自动更新测试服务器工作副本(C#写winform程序实现)
    两台服务器上SQL Server数据库数据互操作示例
    ASP.NET根据URL生成网页缩略图示例程序(C#语言)
    Flutter Widget API
    BPM、BPMN、BPMN2.0概念介绍
    H5多图上传调研
    lIUNX如何加载U盘,光盘
    如何解决exchange2003被中继的问题?(网上转载)
    window无法安装服务
    如何在WORD里面插入不同的页眉和页脚
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7678401.html
Copyright © 2020-2023  润新知