省流:一个数组名写错(甚至是两个毫不相关的数组),结果 A 了。
参考 https://macesuted.blog.luogu.org/solution-P1399 这篇题解写的。
AC code 1(实际错误):
#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define rep(k,l,r) for(int k=l;k<=r;++k)
#define per(k,r,l) for(int k=r;k>=l;--k)
#define cl(f,x) memset(f,x,sizeof(f))
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
using namespace std;
const int N=1e6+5;
int head[N],len=1;
struct node {
int from,to,w,nxt;
}; node edge[N<<1];
void add_edge(int u,int v,int w) {
edge[++len]={u,v,w,head[u]}; head[u]=len;
}
int pre[N],used[N];
vector<PII> root;
void calc(int u) {
int tmp=u;
while(true) {
root.push_back({u,edge[pre[u]].w});
used[u]=true;
u=edge[pre[u]].from;
if(u==tmp||!u)
break;
}
}
bool vis[N];
int dfn[N],p;
bool dfs(int u,int fa) {
dfn[u]=++p;
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to;
if(v!=fa) {
if(dfn[v]) {
if(dfn[v]<dfn[u])
continue;
pre[u]=i^1;
calc(v);
return true;
} else {
pre[v]=i;
if(dfs(v,u))
return true;
}
}
}
return false;
}
int f[N];
void dfs1(int u,int fa) {
vis[u]=true; f[u]=0;
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to,w=edge[i].w;
if(v!=fa&&!used[v]) {
dfs1(v,u);
f[u]=max(f[u],f[v]+w);
}
}
}
int dep[N],rt;
void dfs2(int u,int flag,int fa) {
if(dep[u]>dep[rt])
rt=u;
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to,w=edge[i].w;
if(v!=fa&&(!used[v]||v==flag)) {
dep[v]=dep[u]+w;
dfs2(v,flag,u);
}
}
}
int solve1(int u) {
rt=0;
dfs2(u,u,0);
dep[rt]=0;
dfs2(rt,u,0);
return dep[rt];
}
int val[N],dis[N],a[N],b[N],c[N],d[N];
int solve() {
dfs(1,0);
int len=0,ans=0;
for(auto x:root) {
int u=x.first,w=x.second;
ans=max(ans,solve1(u));
dfs1(u,0);
val[++len]=f[u]; dis[len]=w;
}
int sum=0,maxn=0;
rep(i,1,len) {
sum+=dis[i-1];
a[i]=max(a[i-1],val[i]+sum);
b[i]=max(b[i-1],sum+maxn+val[i]);
chkmax(maxn,a[i]-sum); //这里
}
sum=maxn=0;
int tmp=dis[len]; dis[len]=0;
per(i,len,1) {
sum+=dis[i];
c[i]=max(c[i+1],val[i]+sum);
d[i]=max(d[i+1],val[i]+sum+maxn);
chkmax(maxn,val[i]-sum);
}
int res=b[len];
rep(i,1,len-1)
chkmin(res,max(max(b[i],d[i+1]),a[i]+c[i+1]+tmp));
return max(ans,res);
}
signed main() {
int n;
scanf("%lld",&n);
rep(i,1,n) {
int u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
printf("%.1lf\n",solve()/2.0);
return 0;
}
AC code 2(实际正确):
#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define rep(k,l,r) for(int k=l;k<=r;++k)
#define per(k,r,l) for(int k=r;k>=l;--k)
#define cl(f,x) memset(f,x,sizeof(f))
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
using namespace std;
const int N=1e6+5;
int head[N],len=1;
struct node {
int from,to,w,nxt;
}; node edge[N<<1];
void add_edge(int u,int v,int w) {
edge[++len]={u,v,w,head[u]}; head[u]=len;
}
int pre[N],used[N];
vector<PII> root;
void calc(int u) {
int tmp=u;
while(true) {
root.push_back({u,edge[pre[u]].w});
used[u]=true;
u=edge[pre[u]].from;
if(u==tmp||!u)
break;
}
}
bool vis[N];
int dfn[N],p;
bool dfs(int u,int fa) {
dfn[u]=++p;
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to;
if(v!=fa) {
if(dfn[v]) {
if(dfn[v]<dfn[u])
continue;
pre[u]=i^1;
calc(v);
return true;
} else {
pre[v]=i;
if(dfs(v,u))
return true;
}
}
}
return false;
}
int f[N];
void dfs1(int u,int fa) {
vis[u]=true; f[u]=0;
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to,w=edge[i].w;
if(v!=fa&&!used[v]) {
dfs1(v,u);
f[u]=max(f[u],f[v]+w);
}
}
}
int dep[N],rt;
void dfs2(int u,int flag,int fa) {
if(dep[u]>dep[rt])
rt=u;
for(int i=head[u];i;i=edge[i].nxt) {
int v=edge[i].to,w=edge[i].w;
if(v!=fa&&(!used[v]||v==flag)) {
dep[v]=dep[u]+w;
dfs2(v,flag,u);
}
}
}
int solve1(int u) {
rt=0;
dfs2(u,u,0);
dep[rt]=0;
dfs2(rt,u,0);
return dep[rt];
}
int val[N],dis[N],a[N],b[N],c[N],d[N];
int solve() {
dfs(1,0);
int len=0,ans=0;
for(auto x:root) {
int u=x.first,w=x.second;
ans=max(ans,solve1(u));
dfs1(u,0);
val[++len]=f[u]; dis[len]=w;
}
int sum=0,maxn=0;
rep(i,1,len) {
sum+=dis[i-1];
a[i]=max(a[i-1],val[i]+sum);
b[i]=max(b[i-1],sum+maxn+val[i]);
chkmax(maxn,val[i]-sum); //这里
}
sum=maxn=0;
int tmp=dis[len]; dis[len]=0;
per(i,len,1) {
sum+=dis[i];
c[i]=max(c[i+1],val[i]+sum);
d[i]=max(d[i+1],val[i]+sum+maxn);
chkmax(maxn,val[i]-sum);
}
int res=b[len];
rep(i,1,len-1)
chkmin(res,max(max(b[i],d[i+1]),a[i]+c[i+1]+tmp));
return max(ans,res);
}
signed main() {
int n;
scanf("%lld",&n);
rep(i,1,n) {
int u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
printf("%.1lf\n",solve()/2.0);
return 0;
}
这是交到 CF835F 上面才发现的。
虽然我不想造 hack,但是我认为随便拍一下都能拍出来,希望加强数据。