UVA 10029 Edit Step Ladders ——(DAG求最长路)

  题意:升序的给出一本若干个单词,每个单词都可删除一个字母,添加一个字母或者改变一个字母,如果任意一个操作以后能变成另外一个字典中的单词,那么就连一条有向边,求最长的长度。

  分析:DAG的最长路和最短路在算法竞赛入门里边原原本本有的,结果我现在忘记了,,真是太弱了。。方法就是,用map对应键值(以建图),然后删除操作和修改操作可以看做同一个操作,之后每个操作都是在相应的位置添加一个 '*' 就可以了。想说的有两点,一个是为什么删除和修改可以看做一个操作,其实删除这个操作根本就是多余的,因为一个单词比方说add要和ad匹配,不一定要add删除,而是可以ad添加一个d,所以说删除操作是多余的;第二点是添加操作时,要注意两头都是可以放 '*' 的。

  建完图以后用求DAG的最长路的方法进行dp即可。

  具体见代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <string>
 5 #include <map>
 6 #include <vector>
 7 #include <iostream>
 8 using namespace std;
 9 const int N = 25000+5;
10 
11 string s[N];
12 vector<int> G[N];
13 map<string,int> M;
14 int dp[N];
15 
16 string change(string s,int pos) //删除操作和改变操作可以看做是一样的
17 {
18     string ans = "";
19     for(int i=0;i<s.size();i++)
20     {
21         if(pos == i) ans += '*';
22         else ans += s[i];
23     }
24     return ans;
25 }
26 
27 string add(string s,int pos)
28 {
29     string ans = "";
30     for(int i=0;i<s.size();i++)
31     {
32         if(pos == i) ans += '*';
33         ans += s[i];
34     }
35     if(pos == s.size()) ans += '*';
36     return ans;
37 }
38 
39 int dfs(int x)   //dfs求DAG的最长边
40 {
41     if(dp[x] != -1) return dp[x];
42     int ans = 0;
43     for(int i=0;i<G[x].size();i++)
44     {
45         int v = G[x][i];
46         ans = max(ans,dfs(v));
47     }
48     return dp[x] = ans + 1;
49 }
50 
51 int main()
52 {
53     int cnt = 0;
54     while(cin>>s[cnt++]);
55 
56     for(int i=0;i<cnt;i++)
57     {
58         for(int j=0;j<s[i].size();j++)
59         {
60             string t = change(s[i],j);
61             if(M.count(t))
62             {
63                 G[M[t]].push_back(i);
64             }
65             M[t] = i;
66         }
67 
68         for(int j=0;j<=s[i].size();j++)
69         {
70             string t = add(s[i],j);
71             if(M.count(t))
72             {
73                 G[M[t]].push_back(i);
74             }
75             M[t]=i;
76         }
77     }
78 
79     memset(dp,-1,sizeof(dp));
80     int ans = 0;
81     for(int i=0;i<cnt;i++)
82     {
83         ans = max(ans,dfs(i));
84     }
85 
86     printf("%d
",ans);
87     return 0;
88 }
原文地址:https://www.cnblogs.com/zzyDS/p/5650530.html