1. 程式人生 > >【XSY1552】自動機 構造

【XSY1552】自動機 構造

代碼 math tdi amp 滿足 ble 題目 OS ace

題目大意

  給你一個自動機,包含\(n\)個狀態,指令集為前\(m\)個小寫字母,對於每個狀態\(s\)和每個指令\(i\),自動機均有後繼\(T(s,i)\)。請你求出一個長度不超過\(2^{20}\)的指令序列,使得無論自動機當前處在哪個狀態(包括初始狀態),按順序執行指令序列的所有指令後,自動機都處於初始狀態\(1\)。無解輸出\([impossible]\)

  \(1\leq n\leq 100,1\leq m\leq 26\)

題解

  首先要證明一個結論:原問題有解等價於對於任意狀態\(i\),都存在一個指令序列\(S_i\)使得\(T(s,S_i)=1\)\(T(1,S_i)=1\)

  必要性顯然。如果不存在\(S_i\),那麽狀態\(i\)和狀態\(1\)一定不可能同時轉移到狀態\(1\)

  對於充分性,我們考慮所有當前可能的狀態集合\(U\)。一開始\(U=\{1,2,3\ldots n\}\)。每次我們任選\(U\)中一個狀態\(t\),執行\(S_t\)。這樣我們會得到一個集合\(U‘\),滿足\(1\in U‘\)\(|U‘|<|U|\)。這樣我們經過若幹步後可以得到\(U=\{1\}\)。我們把所有\(S_t\)連在一起得到一個指令序列\(S\),易證\(S\)是滿足要求的。

  所以我們每次任選\(U\)中的一個狀態\(t\),求出\(S_t\)

,然後執行\(S_t\),直到\(|U|=1\)為止。

  對於狀態\(i\),求\(S_i\)的時間復雜度是\(O(n^2)\)的,執行\(S_i\)\(O(n^3)\)的,總共要執行\(O(n)\)次,所以時間復雜度是\(O(n^4)\)的。

  每個\(S_i\)的長度是\(O(n^2)\)的,總共要執行\(O(n)\)次,所以答案的長度是\(O(n^3)\)

代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility> using namespace std; typedef long long ll; typedef pair<int,int> pii; int a[110][30]; int n,m; char s[10000010]; int cnt; int c[110]; int d[110]; int vis[110][110]; int st[10010]; int top; int dfs(int x,int y) { if(x==1&&y==1) return 1; vis[x][y]=1; int i; for(i=1;i<=m;i++) { int lx=a[x][i]; int ly=a[y][i]; if(!vis[lx][ly]) { st[++top]=i; if(dfs(lx,ly)) return 1; top--; } } return 0; } int main() { scanf("%d%d",&n,&m); int i,j; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); a[i][j]++; } cnt=0; for(i=1;i<=n;i++) c[i]=i; int now=n; while(now>1) { memset(vis,0,sizeof vis); top=0; if(!dfs(1,c[2])) { printf("[impossible]"); return 0; } for(i=1;i<=top;i++) { s[++cnt]=st[i]+‘a‘-1; for(j=1;j<=now;j++) c[j]=a[c[j]][st[i]]; } sort(c+1,c+now+1); now=unique(c+1,c+now+1)-c-1; } s[cnt+1]=\0; printf("%s\n",s+1); return 0; }

【XSY1552】自動機 構造