题目:
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 n−1 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
1≤n≤2⋅104
1≤ai,bi≤n
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; }