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\n",ans);
87     return 0;
88 }
时间: 2024-07-31 07:57:07

UVA 10029 Edit Step Ladders ——(DAG求最长路)的相关文章

UVA - 10029 Edit Step Ladders (二分+hash)

Description 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 transformatio

POJ - 2564 Edit Step Ladders

题意:题目按字典序给你多个字符串,判断如果一个字符串通过加,减,变一个字母的情况下可以变成另一个字符串的话,就代表他们之间有一个阶梯,求最多的阶梯 思路:首先我们应该想到这个有点LIS的感觉,然后我们可以采用记忆化搜索,然后就是每当一个字符串进行相应的变化后就去查找后面是否有这个字符串,依次找下去,判断最大值,重点是要通过HASH来优化 #include <iostream> #include <cstdio> #include <cstring> #include &

UVA10029 - Edit Step Ladders(LIS)

题目大意:UVA10029 - Edit Step Ladders(LIS) 题目大意:给你一个按照字典序读入的单词,然后要求你找出最长的序列,要求这个最长的序列也要满足字典序,并且后一个是由前一个单词,由在任意的地方替换,增加,删除一个字符变换来的. 解题思路:LIS.但是这里的O(n^2) 25000,超时.但是查找符合的单词有个规律,符合变换要求的单词的长度是有要求的,必须相差小于等于1.并且数据中相同长度的单词不会超过45个,那么就可以把这些单词按照长度分类,那么查找的时候就是45 *

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;amp;&amp;amp; SPFA求最长路 &amp;amp;&amp;amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

zoj3795 Grouping --- 强连通,求最长路

给定图,求把至少把图拆成几个集合能够使集合内的点没有直接或间接关系. 首先由题意可得图中可能含环,而环里面的点肯定是要拆开的. 缩点建图得DAG图,可以想象一下..把图从入度为零的点向下展开,位于同一层的点放在一个集合是没有关系的, 那么题目所求的问题就转化成求图中最长路的问题了. 这个题的实质和 这题 其实是一模一样的.. #include <iostream> #include <cstring> #include <string> #include <cst

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

HDU - 6201 transaction transaction transaction(spfa求最长路)

题意:有n个点,n-1条边的无向图,已知每个点书的售价,以及在边上行走的路费,问任选两个点作为起点和终点,能获得的最大利益是多少. 分析: 1.从某个结点出发,首先需要在该结点a花费price[a]买书,然后再在边上行走,到达目的地后,在目的地b获得price[b]. 2.因此可以建立两个虚拟结点, 虚拟结点1连向n个点,边权分别为-price[i],表示以i为起点,需花费price[i]买书. n个点连向虚拟结点2,边权分别为price[i],表示以i为终点,通过卖书可得price[i]. 3

poj 3592 Instantaneous Transference 强连通图 缩点 再求最长路

1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<stack> 5 #include<queue> 6 using namespace std; 7 #define maxx 44 8 #define maxx2 44*44 9 #define INF 99999999 10 char s[maxx][maxx]; 11 bool tong[maxx2

zoj-3795-Grouping-tarjan缩点求最长路

用tarjan进行缩点. 然后用dfs求最长路.水体... #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<stack> using namespace std; #define maxn 110000 vector<int>ol