This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,u,w,vis[1000005],no[1000005],is[1000005];
int pt,done,cycle[1000005],bck[1000005],mx,ans;
int node,dist,dp[1000005],par[2000005],we[2000005];
vector<pair<int,int>> g[1000005];
void dfs(int x,int p){
if (done) return;
if (vis[x]){
int cnt=0;
for (auto i:g[x]) cnt+=i.first==p;
if (cnt==2){
cycle[++pt]=x;
cycle[++pt]=p;
is[x]=true; is[p]=true;
}
else {
while (p!=x){
is[p]=true;
cycle[++pt]=p;
p=bck[p];
if (p==-1) break;
}
is[x]=true; cycle[++pt]=x;
}
done=true;
}
else {
vis[x]=1; bck[x]=p;
for (auto i:g[x]){
if (i.first!=p) dfs(i.first,x);
}
}
}
void mem(int x){
no[x]=1;
for (auto i:g[x]){
if (!no[i.first]) mem(i.first);
}
}
void dfs1(int x,int p,int d){
if (d>dist) {
node=x; dist=d;
}
for (auto i:g[x]) {
if (i.first!=p && !is[i.first]) dfs1(i.first,x,d+i.second);
}
}
void treedp(int x,int p){
for (auto i:g[x]){
if (is[i.first] || i.first==p) continue;
treedp(i.first,x);
}
for (auto i:g[x]){
if (is[i.first] || i.first==p) continue;
dp[x]=max(dp[x],dp[i.first]+i.second);
}
if (p==-1){
vector <int> q;
for (auto i:g[x]){
if (is[i.first] || i.first==p) continue;
q.push_back(dp[i.first]+i.second);
}
sort(q.begin(),q.end(),greater<int>());
if (q.size()>1){
mx=max(mx,q[0]+q[1]);
}
if (q.size()) mx=max(q[0],mx);
}
}
int weight(int x,int tar){
for (auto i:g[x]) if (i.first==tar) return i.second;
return 0;
}
void work(){
int sum=0;
priority_queue<pair<int,int>> q;
for (int i=2;i<=pt;i++) we[i]=we[i+pt]=weight(cycle[i-1],cycle[i]);
we[pt+1]=weight(cycle[pt],cycle[1]);
for (int i=1;i<=2*pt;i++) par[i]=par[i-1]+we[i];
for (int i=2;i<=pt;i++) q.push({par[i]+dp[cycle[i]],i});
for (int i=1;i<=pt;i++){
while (!q.empty() && q.top().second<=i) q.pop();
if (!q.empty()) mx=max(mx,q.top().first+dp[cycle[i]]-sum);
// cout<<i<<" "<<q.top().first+dp[cycle[i]]-sum<<"\n";
sum+=we[i+1]; q.push({par[pt+i]-par[i+1]+dp[cycle[i]]+sum,pt+i});
}
}
signed main(){
cin>>n;
for (int i=1;i<=n;i++){
cin>>u>>w;
g[i].push_back({u,w});
g[u].push_back({i,w});
bck[i]=-1;
}
for (int i=1;i<=n;i++){
if (no[i]) continue;
node=mx=dist=done=pt=0;
dfs(i,-1); mem(i);
if (done){
for (int j=1;j<=pt;j++){
treedp(cycle[j],-1);
for (auto k:g[cycle[j]]){
if (is[k.first]) continue;
node=dist=0;
dfs1(k.first,-1,0);
dfs1(node,-1,0);
mx=max(mx,dist);
}
}
if (pt==2){
int tmp=0;
for (auto j:g[cycle[1]]){
if (j.first==cycle[2]) tmp=max(tmp,j.second);
}
mx=max(mx,dp[cycle[1]]+dp[cycle[2]]+tmp);
}
else {
work();
reverse(cycle+1,cycle+1+pt);
work();
}
}
else {
dfs1(i,-1,0);
dfs1(node,-1,0);
mx=max(mx,dist);
}
// cout<<mx<<"\n";
ans+=mx;
}
cout<<ans<<"\n";
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |