記憶體限制:512 mib 時間限制:1000 ms 標準輸入輸出
題目型別:傳統 評測方式:文字比較
上傳者: 1bentong
提交提交記錄
統計討論
測試資料
題目描述
原題來自:hnoi 2006
給定 n個字串 s1,s2,⋯,sn 要求找到乙個最短的字串 t,使得這 n 個字串都是 t 的子串。
輸入格式
第一行是乙個正整數 n,表示給定的字串的個數;
以下的 n行,每行有乙個全由大寫字母組成的字串。
輸出格式
只有一行,為找到的最短的字串 t。
在保證最短的前提下,如果有多個字串都滿足要求,那麼必須輸出按字典序排列的第乙個。
樣例樣例輸入
2
abcd
bcdabc
樣例輸出
abcdabc
資料範圍與提示
對於全部資料,1≤n≤12,1≤∣si∣≤50。
題意:(掛loj是因為我的解法在bzoj上t了並且我不想調qaq)
給你$n$個字串,求他們的最短母串,即求乙個最短字串使得這$n$個字串都是它的子串。若長度相同輸出字典序最小的。
題解:建出$ac$自動機後問題轉化成找一條最短的路徑覆蓋所有$end$節點。
那麼我們可以考慮對每個節點維護乙個壓縮狀態表示從根走到該點包含了哪些字串。
然後從根開始沿$bfs$序遍歷(保證字典序最小)並記錄路徑,若合法則輸出答案。
這題主要是教會了我乙個真理:
當你發現某個**已經改不出來的時候,重構**總是會給你驚喜……
**:
#include#include#include
#include
#include
using
namespace
std;
#define maxn 15
#define maxm 605
#define ll long long
struct
nodetree[maxm];
struct
wayp[maxm*(1
,nxt[maxm];
bool vis[maxm][1
str[maxn],ans[maxn];
inline
intread()
inline
void add(int p,char *str)
tree[u].s|=(1
;
}inline
void
get_nxt()
else tree[u].son[i]=tree[nxt[u]].son[i];}}
return;}
inline
void solve(int
n)
for(int i=0;i<26;i++)
}hd++;
}return;}
intmain()
bzoj1195 最短母串
1 練習了string類,string中查詢,找不到的話會返回 s.npos乙個變數,而不是返回一般的s.end 2 這題還可以,ac自動機上狀壓bfs,找最短路,實際上是dp,但是轉移都是加1,所以可以抽象為邊長為一從起始狀態到最終狀態的最短路,因為為邊長1,又可以轉為bfs。3 include ...
2017 10 5 最短母串 思考記錄
這個題n 15,可以用10表示選取情況下的最優值 預處理兩個串之間的連線關係,然後列舉狀態轉移 然而這個題還要輸出方案,而且還不讓你開空間。所以只能記錄前繼動態判斷 所以十分難寫難調 碼 include include includeusing namespace std int n,i,j,k,l...
習題 最短母串(狀壓)
題目 記憶體限制 512 mib時間限制 1000 ms標準輸入輸出 題目型別 傳統評測方式 文字比較 題目描述 給定n 個字串 要求找到乙個最短的字串 使得這 n個字串都是它 的子串。輸入格式 第一行是乙個正整數 表示給定的字串的個數 以下的 n 1 行,每行有乙個全由大寫字母組成的字串。輸出格式...