1. HashTable<int,bool> visited(0); 2. HashTable<int,int> M(0); 3. 4. int mystery(Digraph G, int vid) { 5. if (! visited[vid]) { 6. visited[vid] = 1; 7. M[vid] = vid; 8. Array<int> out_nbrs = G.out_nbrs(vid); 9. for (int i = 0; i < out_nbrs.size(); ++i) { 10. int P = mystery(G, out_nbrs[i]); 11. if (P > M[vid]) M[vid] = P; 12. } 13. } 14. return M[vid]; 15.}

Here is an example graph, too:

- vertex set = {1, 2, 3, 4, 5, 6, 7, 8, 9}
- directed edges = { (1,2), (1,3), (2,4), (2,5), (4,7), (4,8), (3,6), (3,7), (2,6), (1,4), (5,6), (1,7) }

1A. Run mystery(G, 3) on the digraph G above. What are the values of (M[1], M[2], ..., M[9]) when the algorithm finishes.

1B. Suppose G is ANY digraph without cycles. Describe, in words, what mystery(G, s) returns. (For example "mystery(G,s) counts the number of nodes reachable from vertex s" except that is the wrong answer.)

1C. Over all input graphs with N vertices and M edges, what is the worst-case running time of mystery(G,v)? (Use big-O notation to give your answer.) Explain, carefully, why.

1D. Carefully explain your reasoning that makes you believe your answer to 1B is correct. (If you are not sure that it is correct, be frank about what your doubts are.)

1. HashTable<int,bool> visited(0); 2. HashTable<int,int> S(0); 3. 4. int mystery2(Digraph G, int vid, int vid2) { 5. if (! visited[vid]) { 6. visited[vid] = 1; 7. if (vid == vid2) S[vid] = 1; // this line changed 8. Array<int> out_nbrs = G.out_nbrs(vid); 9. for (int i = 0; i < out_nbrs.size(); ++i) { 10. int P = mystery2(G, out_nbrs[i], vid2); 11. S[vid] += P; // this line changed 10. } 11. } 10. return S[vid]; 11.}

2A. Run mystery2(G, 1, 6) on the example graph from problem 1. What are the values S[1], S[2], ..., S[9] when the algorithm finishes?

2B. In words, if G is ANY directed acyclic graph, what does mystery2(G, s, t) return?

- (3, 1, 4, 1, 5, 9, 2)

3A. Find the longest ascending subsequence within this sequence:

- S = (9, 13, 11, 8, 18, 18, 0, 3, 1, 0, 8, 6, 14, 8, 16, 7) .

3B. Suppose A is an array of N integers. For i=0,1,...,N-1, define
LAS[i] to be the length of the longest ascending subsequence
within (A[0],A[1],A[2],...,A[i]) * that ends with A[i] *.

For example, for the sequence S, above, we have

- LAS[0] = 1, LAS[1] = 2, LAS[2] = 2, LAS[3] = 1, ...

3C. Describe a a recurrence relation between LAS[i]
and the values (LAS[0], LAS[1], ..., LAS[i-1]) and the values (A[0], A[1], ..., A[i]).
(one that holds for *any* sequence of N integers,
where N can be any positive integer).
Hint: your rule should be implementable in O(i) time,
once the values (LAS[0], LAS[1], ..., LAS[i-1]) have been computed.

Another hint: a longest ascending subsequence ending at A[i], if you remove A[i], gives either the empty sequence, or it gives a longest ascending subsequence ending at some A[j] for j < i and A[j] < A[i].

3D. Describe an efficient algorithm for computing the length of the longest ascending subsequence, given a sequence (A[0], A[1], A[2], ..., A[N]). Use pseudo-code to describe your algorithm. What is the running time of your algorithm?

3E. Prove that your recurrence relation from 3C is correct.