https://www.zybuluo.com/ysner/note/1250303

题面

给定\(s\)个自动机,如果某个自动机\(A\)能产生的所有串都能在自动机\(B\)中产生(即走相同\(0/1\)路径后,同时碰到输出元),则称\(B\)是\(A\)的一个升级,求最长升级序列长度。

  • \(s,n\leq50\)

解析

辣鸡题目考语文

然而看懂题后还是很简单的。

判断\(B\)是否为\(A\)的升级,就每次分别在\(A,B\)走相同的\(0/1\)路径(因每个点有两个出度),若在\(A\)碰到一个输出元,而此时\(B\)没有,就说明不是升级。

是升级就把\(A->B\)边权赋为\(1\)。

最后\(Floyd\)跑最长路即可。

(或者建边+拓扑排序也可以)。

但要注意,如果有两个完全相同的自动机,两者都会判为对方的升级,这时需强制只有一个方向边权赋为\(1\)(建边的话跑\(Tarjan\)缩点)。

没清空queue调了?h

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define ll long long
#define re register
#define il inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a);(b))
#define N 100
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
int s,n,m,h[N],out[N][N],a[N][N][2],dis[N][N];
ll ans;
bool vis[N][N];
struct node{int x,y;};
queue<node>Q;
il int gi()
{
re int x=0,t=1;
re char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
il int check(re int s1,re int s2)
{
//printf("!!!%d %d\n",s1,s2);
while(!Q.empty()) Q.pop();
memset(vis,0,sizeof(vis));
Q.push((node){1,1});
while(!Q.empty())
{
re node now=Q.front(),tmp;Q.pop();//gg
if(out[s1][now.x]&&!out[s2][now.y]) return 0;
tmp.x=a[s1][now.x][0];tmp.y=a[s2][now.y][0];
if(!vis[tmp.x][tmp.y]) vis[tmp.x][tmp.y]=1,Q.push(tmp);
tmp.x=a[s1][now.x][1];tmp.y=a[s2][now.y][1];
if(!vis[tmp.x][tmp.y]) vis[tmp.x][tmp.y]=1,Q.push(tmp);
}
return 1;
}
int main()
{
s=gi();
fp(i,1,s)
{
n=gi();m=gi();
//fp(j,1,n) a[i][j][0]=a[i][j][1]=1;
fp(j,1,m) out[i][gi()+1]=1;
fp(j,1,n)
{
re int u=gi()+1,v=gi()+1;
a[i][j][0]=u;a[i][j][1]=v;
}
}
memset(dis,-63,sizeof(dis));
fp(i,1,s)
fp(j,1,s)
if(i!=j&&check(i,j)&&dis[j][i]<0) dis[i][j]=1;//注意到有完全相同的自动机
//fp(i,1,s) fp(j,1,s) printf("%d %d %d\n",i,j,dis[i][j]);
fp(k,1,s)
fp(i,1,s)
fp(j,1,s)
//if(dis[i][j]<dis[i][k]+dis[k][j]&&dis[i][k]&&dis[k][j]
dis[i][j]=max(dis[i][j],dis[i][k]+dis[k][j]),ans=max(ans,dis[i][j]);
printf("%lld\n",ans+1);
return 0;
}

最新文章

  1. android doc里面adb连接出现问题的解决方法
  2. 浅谈WebSocket
  3. Web API应用支持HTTPS的经验总结
  4. EC6 map 和 set
  5. 解决SlidingMenu和SwipeBackLayout右滑事件冲突问题
  6. zw版【转发&#183;台湾nvp系列Delphi例程】HALCON Component Histogram
  7. 在MAC OS 下配置python + Flask ,并支持pyCharm编辑器
  8. 深度学习论文笔记-Deep Learning Face Representation from Predicting 10,000 Classes
  9. Secure CRT 如何连接虚拟机里面的CentOS系统 当主机使用有线网的时候 作者原创 欢迎转载
  10. django随笔说明
  11. Compile C++ code in Matlab with OpenCV support
  12. 尚学堂马士兵struts2 课堂笔记(四)
  13. mysql免安装版的下载与安装
  14. webRTC中音频相关的netEQ(三):存取包和延时计算
  15. @ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常==》记录
  16. codeforces569B
  17. Python- - -练习目录
  18. divide&amp;conquer:find max array
  19. mbr看图
  20. HDU4609:3-idiots(FFT)

热门文章

  1. 数据导出为Excel(未完)
  2. 牛客多校Round 8
  3. 01java基础
  4. 洛谷——P1349 广义斐波那契数列(矩阵加速)
  5. 反片语(Ananagrams,Uva 156)
  6. CentOS7 安装、配置 Memcached
  7. 【Codeforces 9989C】A Mist of Florescence
  8. 【Codeforces 493C】Vasya and Basketball
  9. RSA的共模攻击
  10. 最小生成树 C - Building a Space Station