发现自己的做法假了之后,改成了单调队列正解了。但是还是WA了#3#4,TLE #15。来回改了2个小时,但是因为拿不到测试点,还没有成功,求各位大佬帮帮忙看看代码,救救孩子吧。
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int N=2e6+10;
int n,a[N];
#define ll long long
#define int long long
int he[N],ne[N],to[N],tot=1;
long long w[N],d[N],dist[N],ans,sum,ringlen;
ll read(){
ll x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar(); }
return x;
}
void addedge (int x,int y,long long z){
to[++tot]=y;
ne[tot]=he[x];
he[x]=tot;
w[tot]=z;
}
int low[N],dfo[N],cnt=0,edcccnt=0;
stack <int> q;
vector <int> edcc[N];
bool st[N],bridge[N],node[N],vis[N];
void tarjan(int now,int inedge){
dfo[now]=low[now]=++cnt;
q.push(now);
st[now]=1;
for(int i=he[now];i;i=ne[i]){
int v=to[i];
if(!dfo[v]){
tarjan(v,i);
low[now]=min(low[now],low[v]);
if(low[v]>dfo[now]){
bridge[i]=bridge[i^1]=true;
++edcccnt;
int p;
do{
p=q.top();
edcc[edcccnt].push_back(p);
st[p]=0;
q.pop();
}
while(p!=v);
if(edcc[edcccnt].size()==1){
edcc[edcccnt].clear();
--edcccnt;
}
}
}
else if(i!=(inedge^1)){
low[now]=min(low[now],dfo[v]);
}
}
}
void dp(int now){
st[now]=true;
for(int i=he[now];i;i=ne[i]){
int v=to[i];
if(st[v]||node[v]){
continue;
}
dp(v);
sum=max(sum,(long long)d[now]+d[v]+w[i]);
d[now]=max(d[now],(long long)d[v]+w[i]);
}
}
int dfs(int now,int fa,long long s,int inedge){
// cout<<"from "<<fa<<" to "<<now<<" the s: "<<s<<endl;
dist[++cnt]=s;
a[cnt]=now;
if(vis[now]==true){
return s;
}
vis[now]=true;
for(int i=he[now];i;i=ne[i]){
int v=to[i];
if(node[v]==false||i==(inedge^1)){
continue;
}
// cout<<"next is "<<v<<endl;
return dfs(v,now,s+w[i],i);
}
}
signed main(){
n=read();
int x,y;
long long z;
for(int i=1;i<=n;i++){
y=read();z=read();
x=i;
if(x==y){
continue;
}
addedge(x,y,z);
addedge(y,x,z);
}
for(int i=1;i<=n;i++){
if(!st[i]){
addedge(i+n,i,0);
tarjan(i+n,0);
}
}
memset(st,0,sizeof st);
for(int i=1;i<=edcccnt;i++){
sum=cnt=0;
vector<int>::iterator it;
for(it=edcc[i].begin();it!=edcc[i].end();it++){
node[*it]=true;
// cout<<*it<<" ";
}
// cout<<endl;
ringlen=dfs(*edcc[i].begin(),0,0,-1);
for(int j=1;j<=cnt;j++){
// cout<<j<<" : "<<a[j]<<" "<<dist[j]<<endl;
}
for(int j=cnt+1;j<=(cnt-1)*2;j++){
a[j]=a[j-(cnt-1)];
dist[j]=dist[j-1]+(dist[j-(cnt-1)]-dist[j-(cnt-1)-1]);
// cout<<j<<" : "<<a[j]<<" "<<dist[j]<<endl;
}
--cnt;
// cout<<"ringlen: "<<ringlen<<endl;
// cout<<"cnt : "<<cnt<<endl;
for(int j=1;j<=cnt;j++){
dp(a[j]);
// cout<<a[j]<<" : "<<sum<<endl;
}
int l=1,r=0,q[N];
for(int k=1;k<=2*cnt;k++){
while(l<=r&&k-q[l]>=cnt){
l++;
}
if(l<=r){
sum=max(sum,d[a[k]]+d[a[q[l]]]+(dist[k]-dist[q[l]]));
}
while(l<=r&&d[a[k]]-dist[k]>=d[a[q[r]]]-dist[q[r]]){
r--;
}
q[++r]=k;
// cout<<l<<" - "<<r<<" "<<dist[r]-dist[l]<<" "<<endl;
}
ans+=sum;
}
printf("%lld\n",ans);
}