Hackerrank (1): CodeStorm 2015 > Little Alexey's Tree

题目:

Problem Statement

Little Alexey was playing with trees while studying powerful tree algorithms.

Recently, he discovered a tree with n vertices. On each edge, there's a lowercase English letter written on it.

If we concatenate all the letters on the path from vertex u to vertex v , we can write some word. Little Alexey is interested in the largest lexicographical words.

For every vertex u , find a vertex v to create a string that is lexicographically largest by concatenating all the letters on the path from u to v . If the vertices are lexicographically the same size, find the one with the largest number.

Input Format

On the first line, you are given a single positive integer n : the number of vertices in the tree.Each of the next n1 lines contains space-separated positive integers ai , bi and a character ci , that describes an edge between ai and bi with ci written on the edge.

Constraints

1n2104
1ai,bin
ci is a lowercase English letter

Output Format

Print n space-separated positive integers: the answer for the task.

Sample Input 1

4
1 2 a
2 3 a
3 4 b

Sample Output 1

4 4 4 1

Sample Input 2

9
1 2 b
2 3 a
2 4 c
1 6 c
6 5 d
6 7 c
1 9 d
9 8 e

Sample Output 2

8 4 4 8 8 5 5 5 8

Explanation

Let's look at the first sample. A way between 1 and 4 corresponds to string aab . A way between 2 and 4 corresponds to ab . A way between 3 and 4 corresponds to b . A way between 4 and 1 corresponds to baa . It's easy to see that these paths are the lexicographically largest.

题解:

通过了22个Case,还有36个Case超时,算法应该是对的。

C++版:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <set>
#include <stack>
using namespace std;

struct comparator {
    bool operator() (const pair<int, char>& a, const pair<int, char>& b) {
        return a.second >= b.second;
    }
};

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    int numberOfLines;
    cin >> numberOfLines;
    if(numberOfLines == 1) {
        cout << 1 << endl;
        return 0;
    }
    unordered_map<int, set<pair<int, char>, comparator>> tree;
    for(int i = 0; i < numberOfLines - 1; i++) {
        int start, end;
        char c;
        cin >> start >> end >> c;
        if(tree.find(start) == tree.end()) {
            set<pair<int, char>, comparator> edges;
            edges.insert(pair<int, char>(end, c));
            tree.insert(pair<int, set<pair<int, char>, comparator>>(start, edges));
        } else {
            set<pair<int, char>, comparator> s = tree[start];
            s.insert(pair<int, char>(end, c));
            tree[start].insert(pair<int, char>(end, c));
        }
        if(tree.find(end) == tree.end()) {
            set<pair<int, char>, comparator> edges;
            edges.insert(pair<int, char>(start, c));
            tree.insert(pair<int, set<pair<int, char>, comparator>>(end, edges));
        } else {
            tree[end].insert(pair<int, char>(start, c));
        }
    }
    
    for(int i = 1; i <= numberOfLines; i++) {
        vector<pair<string, int>> results;
        stack<pair<pair<int, int>, string>> path;
        auto iter = tree[i].begin();
        string s = "";
        char c = iter->second;

        s += c;
        do {
            pair<int, int> p(iter->first, i);
            path.push(pair<pair<int, int>, string>(p, s));
            iter++;
        } while (iter != tree[i].end() && iter->second == c);

        while(!path.empty()) {
            int cur = path.top().first.first;
            int last = path.top().first.second;
            string curS = path.top().second;
            
            path.pop();
            
            auto iter2 = tree[cur].begin();

            if(iter2->first == last)
                iter2++;
            if(iter2 == tree[cur].end()) {
                results.push_back(pair<string, int>(curS, cur));
                continue;
            }
            char c1 = iter2->second;
            curS += c1;
            for(iter2; iter2 != tree[cur].end() && iter2->second == c1; iter2++) {
                if(iter2->first == last)
                    continue;
                pair<int, int> p(iter2->first, cur);
                path.push(pair<pair<int, int>, string>(p, curS));
            }
        }
        string largestS = "";
        int largestI = 0;
        for(int j = 0; j < results.size(); j++) {
            if(results[j].first == largestS) {
                largestI = max(largestI, results[j].second);
            } else if(results[j].first > largestS) {
                largestS = results[j].first;
                largestI = results[j].second;
            }
        }
        cout << largestI << " ";
    }
    
    return 0;
}

你可能感兴趣的:(Algorithm,面试题,hackerrank)