题目:
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;
}