#include <bits/stdc++.h>
using namespace std;
const int kN = 1e6 + 7;
struct FastVector{
long long arr[kN], sz;
FastVector(int sz = 0){
this->sz = sz;
}
void resize(int sz = 0){
this->sz = sz;
}
void clear(){
sz = 0;
}
void push_back(int x){
arr[sz++] = x;
}
long long& operator[](int idx){
return arr[idx];
}
inline int size(){
return sz;
}
};
vector<pair<int, int> > adj[kN];
bool vis[kN];
int depth[kN];
FastVector path, longest_path[2];
int prohibited[2];
void get_diameter_length(int u, int par){
longest_path[0][u] = 0;
longest_path[1][u] = 0;
for(auto [to, len]: adj[u]){
if(to == par)
continue;
get_diameter_length(to, u);
longest_path[0][u] = max(longest_path[0][u], longest_path[0][to]);
longest_path[0][u] = max(longest_path[0][u], longest_path[1][to] + len + longest_path[1][u]);
longest_path[1][u] = max(longest_path[1][u], longest_path[1][to] + len);
}
}
bool get_path(FastVector &path, int u, int par, const pair<int, int> &back_edge){
if(u == back_edge.second){
path.push_back(u);
return true;
}
for(auto [to, len]: adj[u]){
if(to == par )
continue;
if(get_path(path, to, u, back_edge)){
path.push_back(u);
return true;
}
}
return false;
}
long long get_longest_path_length(int u, int par, const int prohibited[]){
long long ans = 0;
for(auto [to, len]: adj[u]){
if(to == par || to == prohibited[0] || to == prohibited[1])
continue;
ans = max(ans, get_longest_path_length(to, u, prohibited) + len);
}
return ans;
}
long long get_max_path(const pair<int, int> &back_edge, const int len_back_edge){
get_diameter_length(back_edge.first, -1);
long long ans = longest_path[0][back_edge.first];
path.clear();
get_path(path, back_edge.first, -1, back_edge);
for(int i = 0; i < path.size() / 2; ++i)
swap(path[i], path[(int)path.size() - i - 1]);
longest_path[0].clear();
longest_path[1].clear();
for(int i = 0; i < 2; ++i)
longest_path[i].resize(path.size());
for(int i = 0; i < path.size(); ++i){
if(i == 0)
prohibited[0] = -1;
else
prohibited[0] = path[i - 1];
if(i == path.size() - 1)
prohibited[1] = -1;
else
prohibited[1] = path[i + 1];
longest_path[0][i] = longest_path[1][i] = get_longest_path_length(path[i], -1, prohibited);
}
long long curr_len = 0;
for(int i = 0; i < path.size(); ++i){
longest_path[0][i] += curr_len;
if(i != (int)path.size() - 1){
for(auto [to, len]: adj[path[i]]){
if(to == path[i + 1]){
curr_len += len;
break;
}
}
}
}
curr_len = 0;
for(int i = (int)path.size() - 1; i >= 0; --i){
longest_path[1][i] += curr_len;
if(i != 0){
for(auto [to, len]: adj[path[i]]){
if(to == path[i - 1]){
curr_len += len;
break;
}
}
}
}
for(int i = 1; i < path.size(); ++i)
longest_path[0][i] = max(longest_path[0][i - 1], longest_path[0][i]);
for(int i = (int)path.size() - 2; i >= 0; --i)
longest_path[1][i] = max(longest_path[1][i + 1], longest_path[1][i]);
for(int i = 0; i < (int)path.size() - 1; ++i)
ans = max(ans, longest_path[0][i] + longest_path[1][i + 1] + len_back_edge);
return ans;
}
void build_tree(int u, int par, vector<pair<int, int>> &back_edges, vector<int> &len_back_edges){
vis[u] = true;
if(par == -1)
depth[u] = 0;
else
depth[u] = depth[par] + 1;
bool to_del = false;
int ud, tod, lend;
for(auto [to, len]: adj[u]){
if(to == par)
continue;
if(vis[to]){
if(depth[to] > depth[u]){
back_edges.push_back({to, u});
len_back_edges.push_back(len);
to_del = true;
ud = u;
tod = to;
lend = len;
}
continue;
}
build_tree(to, u, back_edges, len_back_edges);
}
if(to_del){
adj[ud].erase(find(adj[ud].begin(), adj[ud].end(), pair<int, int>{tod, lend}));
adj[tod].erase(find(adj[tod].begin(), adj[tod].end(), pair<int, int>{ud, lend}));
}
}
vector<pair<int, int>> back_edges;
vector<int> len_back_edges;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
for(int u = 1; u <= n; ++u){
int v, len;
cin >> v >> len;
adj[u].push_back({v, len});
adj[v].push_back({u, len});
}
for(int i = 1; i <= n; ++i){
if(!vis[i]){
build_tree(i, -1, back_edges, len_back_edges);
}
}
for(int i = 1; i <= n; ++i)
vis[i] = false;
long long ans = 0;
for(int i = 0; i < back_edges.size(); ++i)
ans += get_max_path(back_edges[i], len_back_edges[i]);
cout << ans << "\n";
}
Compilation message
islands.cpp: In function 'void get_diameter_length(int, int)':
islands.cpp:45:11: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
for(auto [to, len]: adj[u]){
^
islands.cpp: In function 'bool get_path(FastVector&, int, int, const std::pair<int, int>&)':
islands.cpp:62:11: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
for(auto [to, len]: adj[u]){
^
islands.cpp:62:19: warning: unused variable 'len' [-Wunused-variable]
for(auto [to, len]: adj[u]){
^
islands.cpp: In function 'long long int get_longest_path_length(int, int, const int*)':
islands.cpp:76:11: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
for(auto [to, len]: adj[u]){
^
islands.cpp: In function 'long long int get_max_path(const std::pair<int, int>&, int)':
islands.cpp:117:13: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
for(auto [to, len]: adj[path[i]]){
^
islands.cpp:130:13: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
for(auto [to, len]: adj[path[i]]){
^
islands.cpp: In function 'void build_tree(int, int, std::vector<std::pair<int, int> >&, std::vector<int>&)':
islands.cpp:159:11: warning: decomposition declaration only available with -std=c++1z or -std=gnu++1z
for(auto [to, len]: adj[u]){
^
islands.cpp: In function 'int main()':
islands.cpp:213:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(int i = 0; i < back_edges.size(); ++i)
~~^~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
18 ms |
23936 KB |
Output is correct |
2 |
Correct |
18 ms |
23936 KB |
Output is correct |
3 |
Correct |
20 ms |
23936 KB |
Output is correct |
4 |
Correct |
18 ms |
23936 KB |
Output is correct |
5 |
Correct |
18 ms |
23808 KB |
Output is correct |
6 |
Correct |
17 ms |
23808 KB |
Output is correct |
7 |
Correct |
18 ms |
23808 KB |
Output is correct |
8 |
Correct |
18 ms |
23808 KB |
Output is correct |
9 |
Correct |
18 ms |
23808 KB |
Output is correct |
10 |
Correct |
18 ms |
23808 KB |
Output is correct |
11 |
Correct |
18 ms |
23808 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
23936 KB |
Output is correct |
2 |
Correct |
20 ms |
23936 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
20 ms |
23936 KB |
Output is correct |
2 |
Correct |
20 ms |
24448 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
29 ms |
25020 KB |
Output is correct |
2 |
Correct |
56 ms |
28280 KB |
Output is correct |
3 |
Correct |
30 ms |
25088 KB |
Output is correct |
4 |
Correct |
23 ms |
24448 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
49 ms |
29816 KB |
Output is correct |
2 |
Correct |
62 ms |
32248 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
124 ms |
38392 KB |
Output is correct |
2 |
Correct |
133 ms |
47096 KB |
Output is correct |
3 |
Correct |
165 ms |
60664 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
205 ms |
48760 KB |
Output is correct |
2 |
Correct |
263 ms |
82808 KB |
Output is correct |
3 |
Correct |
322 ms |
93816 KB |
Output is correct |
4 |
Correct |
376 ms |
118652 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
422 ms |
83536 KB |
Output is correct |
2 |
Runtime error |
586 ms |
131076 KB |
Execution killed with signal 9 (could be triggered by violating memory limits) |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
456 ms |
131076 KB |
Execution killed with signal 9 (could be triggered by violating memory limits) |
2 |
Halted |
0 ms |
0 KB |
- |