您的位置:首页 > 其它

uva 10029 - Edit Step Ladders(巧妙构图 + Dag最长路)

2014-04-23 18:55 281 查看

Problem C: Edit Step Ladders

An edit step is a transformation from one word x to
another word y such that x and y are
words in the dictionary, and x can be transformed to y by
adding, deleting, or changing one letter. So the transformation from dig to dog or
from dog to do are both edit steps.
An edit step ladder is a lexicographically ordered sequence of words w1, w2,
... wn such that the transformation from wi to wi+1 is
an edit step for all i from 1 to n-1.
For a given dictionary, you are to compute the length of the longest edit step ladder.

Input

The input to your program consists of the dictionary - a set of lower case words in lexicographic order - one per line. No word exceeds 16 letters and there are no more than 25000 words in the dictionary.

Output

The output consists of a single integer, the number of words in the longest edit step ladder.

Sample Input

cat
dig
dog
fig
fin
fine
fog
log
wine

Sample Output

5

很容易想到最长路的建模。关键是,如果用n^2的方法一一比较每两个单词是否能达到去建边,肯定是会超时的。一种巧妙的方法是,考虑每个词所有可能的变化:删除和修改可以看成是一类的。这样,枚举出所有可能生成的词,注意,这里不要枚举所有可能的词的具体情况,这样就要考虑27种变化,事实上,可以用一个通配符比如‘*’代表这个字母可以是任意值。可以证明如果两个生成词相同,则它们一定可以在一步修改内到达。
建好图后再求一个最长路就可以了。
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <stack>
#include <set>
#include <cstring>
#include <stdlib.h>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 25000 + 5;

string s[maxn];
map<string, int> M;
vector<int> G[maxn];

string change(string text, int pos){
    string ret = "";
    for(int i = 0;i < text.length();i++){
        if(i != pos) ret.push_back(text[i]);
        else ret.push_back('*');
    }
    return ret;
}

string add(string text, int pos){
    string ret = "";
    for(int i = 0;i < text.length();i++){
        if(pos == i) ret.push_back('*');
        ret.push_back(text[i]);
    }
    if(pos == text.length())
        ret.push_back('*');
    return ret;
}

int dp[maxn];

int dfs(int x){
    if(dp[x] != -1) return dp[x];
    int Max = 0;
    for(int i = 0;i < G[x].size();i++){
        int from = G[x][i];
        Max = max(Max, dfs(from));
    }
    return dp[x] = 1+Max;
}

int main(){
    int cnt = 0;
    while(cin >> s[cnt++]);
    cnt--;
    M.clear();
    for(int i = 0;i < cnt;i++) G[i].clear();
    for(int i = cnt-1;i >= 0;i--){
        for(int j = 0;j < s[i].length();j++){
            string tem = change(s[i], j);
            if(M.count(tem) > 0){
                G[M[tem]].push_back(i);
            }
            M[tem] = i;
        }
        for(int j = 0;j <= s[i].length();j++){
            string tem = add(s[i], j);
            if(M.count(tem) > 0){
                G[M[tem]].push_back(i);
            }
            M[tem] = i;
        }
    }

    memset(dp, -1, sizeof(dp));
    int ans = 0;
    for(int i = cnt-1;i >= 0;i--){
        ans = max(ans, dfs(i));
    }
    printf("%d\n", ans);

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: