// OB会夏合宿2011 Day3 H : Palindrome Generator #include #include #include #include #include using namespace std; class Node{ public: int diff, Lidx, Ridx, cost; Node(int diff, int Lidx, int Ridx, int cost) : diff(diff), Lidx(Lidx), Ridx(Ridx), cost(cost) {} bool operator < (const Node &nd) const { return cost < nd.cost; } }; int main(){ int N, M; // [回文からはみ出てる文字数][最左文字列の番号][最右文字列の番号] // 文字数 < 10 なら、左に(10-文字数)だけはみ出てる状態 // 文字数 > 10 なら、右に(文字数-10)だけはみ出てる状態 int dp[21][100][100]; string str[100]; const int INF = 1000000007; while(cin >> N >> M){ for(int i=0;i> str[i]; vector< vector > f(N, vector()), b(N, vector()); for(int i=0;i> x >> y; f[x-1].push_back(y-1); b[y-1].push_back(x-1); // 逆向きグラフ } priority_queue qu; memset(dp, 0, sizeof(dp)); // 各文字列について、回文の中心にできる場所を調べて初期状態に追加 for(int i=0;i=0;j--){ bool ok = true; for(int k=0;j+k= c) continue; // 長さが1000超えたらどっかで循環してるんじゃねという嘘っぽい考え if(dp[diff][Lidx][Ridx] > 1000) c = INF; dp[diff][Lidx][Ridx] = c; // 左にはみ出てたら右側に文字列を追加 if(diff <= 10){ for(int i=0;i= 10){ for(int i=0;i