捞贴求助qwq
  • 板块学术版
  • 楼主Refined_heart
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/8/31 20:57
  • 上次更新2023/11/4 08:13:56
查看原帖
捞贴求助qwq
128591
Refined_heart楼主2021/8/31 20:57

求助

现在在 ACWing 上面剩下3个点没过了,这里配上新代码:(更改了代码中dp找树直径的部分),错的点仍然是15 18,答案偏小

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int N=1e6+10;
ll sum[N<<1],val[N];
int head[N],tot,n,m;
struct E{int nxt,to,dis;}e[N<<1];
int st[N],top,vis[N],num,cir[N<<1],cnt;
inline int Max(int x,int y){return x>y?x:y;}
vector<int>Cir[N];
void Get(int node,int x){
	int i;
	for(i=top;i&&st[i]!=x;--i)Cir[node].push_back(st[i]),st[i]=0;
	Cir[node].push_back(x);st[i]=0;
}
void Find_Circle(int x,int fa,int node){
	vis[x]=1;st[++top]=x;
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==fa){continue;}
		if(vis[j]&&Cir[node].empty()){Get(node,j);}
		if(!vis[j])Find_Circle(j,x,node);
	}
	--top;
}
inline void link(int u,int v,int w){
	e[++tot]=(E){head[u],v,w};
	head[u]=tot;
}
#define gc() getchar()
inline int read(){
	int s=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch)){
		s=s*10+ch-'0';
		ch=gc();
	}
	return s;
}
ll ans=-1;
ll f[N],g[N];
void Dp(int x,int fa,int P){
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==fa)continue;
		if(vis[j])continue;
		Dp(j,x,P);
		g[P]=Max(g[P],f[x]+f[j]+e[i].dis);
		f[x]=Max(f[x],f[j]+e[i].dis);
	}
}
int getval(int x,int v){
	for(int i=head[x];i;i=e[i].nxt){
		int j=e[i].to;
		if(j==v)return e[i].dis;
	}
	return -1;
}
int q[N<<1],tail,Head;
ll dp[N<<1];
void solve(int pos,ll &R){
	tail=0;Head=1;
	q[++tail]=1;dp[1]=val[cir[1]];
	for(int i=1;i<=cnt;++i)cir[i+cnt]=cir[i];
	cnt<<=1;
	for(int i=2;i<=cnt;++i){
		int v=getval(cir[i-1],cir[i]);
		sum[i]=sum[i-1]+v;
	}
	for(int i=2;i<=cnt;++i){
		while(Head<=tail&&q[Head]<=i-(cnt/2)+1)++Head;
		dp[i]=val[cir[i]]+sum[i]-sum[q[Head]]+val[cir[q[Head]]];
		while(Head<=tail&&val[cir[i]]-sum[i]>=val[cir[q[tail]]]-sum[q[tail]])--tail;
		q[++tail]=i;
	}
	ll T=-1;
	for(int i=1;i<=cnt;++i)T=Max(T,dp[i]);
	R+=T;
	for(int i=1;i<=cnt;++i)sum[i]=0;
	for(int i=1;i<=cnt;++i)q[i]=0;
}
struct EEE{
	int u,v,w;
}Edge[N];
inline bool cmp(EEE x,EEE y){
	if(x.u==y.u&&x.v==y.v)return x.w>y.w;
	return x.u==y.u?x.v<y.v:x.u<y.u;
}
signed main(){
	freopen("in.txt","r",stdin);
//	freopen("358.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i){
		int a=read(),L=read();
		int u=i,v=a;
		if(u>v)swap(u,v);
		Edge[i]=(EEE){u,v,L};
	}
	sort(Edge+1,Edge+n+1,cmp);
	for(int i=1;i<=n;++i){
		int u=Edge[i].u;
		int v=Edge[i].v;
		if(u==Edge[i-1].u&&v==Edge[i-1].v)continue;
		link(u,v,Edge[i].w);
		link(v,u,Edge[i].w);
	}
	for(int i=1;i<=n;++i){
		if(!vis[i]){
			++num;
			top=0;
			Find_Circle(i,0,num);
			if(Cir[num].empty())Cir[num].push_back(i);
		}
	}
	for(int i=1;i<=n;++i)vis[i]=0;
	for(int i=1;i<=num;++i)
		for(auto v:Cir[i])
			vis[v]=1;
	for(int i=1;i<=n;++i){
		if(!vis[i])continue;
		Dp(i,0,i);
		val[i]=f[i];
	}
//	for(int i=1;i<=n;++i)if(vis[i])printf("(%d %lld %lld):\n",i,f[i],g[i]);
	ll Res=0;
	for(int i=1;i<=num;++i){
		ll mx=-1;
		for(auto v:Cir[i])mx=Max(mx,g[v]);
		Res+=mx;
	}
	ans=Max(Res,ans);
	ll res=0;
	for(int i=1;i<=num;++i){
		int L=Cir[i].size();
		top=0;
		if(L<=1){
			ll mx=-1;
			for(auto v:Cir[i])mx=Max(mx,g[v]);
			res+=mx;
			continue;
		}
		cnt=0;
		for(auto v:Cir[i])cir[++cnt]=v;
		solve(i,res);
	}
	ans=Max(ans,res);
	printf("%lld\n",ans);
	return 0;
}
2021/8/31 20:57
加载中...