70ptsTLE求助
查看原帖
70ptsTLE求助
602932
NumberTrart楼主2025/2/8 14:24
//#pragma GCC optimize(3,"Ofast","inline")
//#pragma GCC optimize(2)
#include<iostream>
#include<vector>
#include<cstring>
//#include<stack>
#define int long long
using namespace std;
const int N=200005;
//vector<int> g[N],w[N];
long long head[2*N],nxt[2*N],g[2*N],w[2*N],cnt=0;
inline void add(int u,int v,int ww)
{
	++cnt;
	g[cnt]=v;
	w[cnt]=ww;
	nxt[cnt]=head[u];
	head[u]=cnt;
}
int n;
inline void getll(long long& n)
{
    n=0;
    long long k=1;
    char c=getchar();
    while((c<'0'||c>'9')&&c!='-') c=getchar();
    if(c=='-') k=-1,c=getchar();
    while('0'<=c&&c<='9') n=n*10+c-'0',c=getchar();
    n*=k;
}
/*inline void getint(int& n)
{
    n=0;
    int k=1;
    char c=getchar();
    while((c<'0'||c>'9')&&c!='-') c=getchar();
    if(c=='-') k=-1,c=getchar();
    while('0'<=c&&c<='9') n=n*10+c-'0',c=getchar();
    n*=k;
}*/
struct ISTREAM{} _cin;
ISTREAM& operator>>(ISTREAM& istr,long long& n){getll(n);return istr;}
//ISTREAM& operator>>(ISTREAM& istr,int& n){getint(n);return istr;}
namespace DFS
{
	int dist[N];
	int farest;
	int p1,p2,p1i;
	//p1==p2: mid is p1
	//p1!=p2: mid is a point between p1 and p2,which is on edge g[p1][p1i]
	int istk[N],top=0;//stores all of the g[][i]
	int Istk[N],Top=0;//maxp
	inline void initdist(int p)
	{
		memset(dist,0x3f,sizeof dist);
		dist[p]=0;
		farest=p;
		p1=p2=p1i=0;
		top=Top=0;
	}
	inline void dfs(int p,int fa)
	{
		//cout<<"dist["<<p<<"]="<<dist[p];
		if(dist[p]>dist[farest])
		{
			farest=p;
			for(int i=1;i<=top;++i) Istk[i]=istk[i];
			Top=top;
			//cout<<" is the farest";
		}
		//cout<<endl;
		for(int i=head[p];i;i=nxt[i])
			if(g[i]!=fa)
			{
				dist[g[i]]=dist[p]+w[i];
				istk[++top]=i;//pushstack
				dfs(g[i],p);
				--top;//popstack
			}
	}
	inline void getmid(int P1)
	{
		p1=P1;
		for(int i=1;i<=Top;++i)
		{
			p2=g[Istk[i]];
			if(dist[p2]*2<dist[farest])//haven't reach yet
				p1=p2;
			else if(dist[p2]*2==dist[farest])//a point
			{
				p1=p2;
				return;
			}
			else
			{
				p1i=Istk[i];
				return;
			}
		}
	}
}
namespace DP
{
	int f[N],g[N];
	inline bool dfs(int p,int fa,int D)//g=int[]  ::g=vector<int>[]
	{
		//cout<<"dfs("<<p<<","<<fa<<","<<D<<')'<<'\n';
		f[p]=0;
		g[p]=0;
		for(int i=::head[p];i;i=nxt[i])
			if(::g[i]!=fa)
				if(dfs(::g[i],p,D))
				{
					f[p]++;
					if(f[p]>1) g[p]=0;
					else g[p]=1+g[::g[i]];
				}
		if(DFS::dist[p]==D) f[p]++,g[p]=0;
		//cout<<"f["<<p<<"]="<<f[p]<<" g["<<p<<"]="<<g[p]<<'\n';
		return f[p];
	}
}
signed main()
{
	//ios::sync_with_stdio(false);
	_cin>>n;
	for(int i=1;i<n;++i)
	{
		int x,y,z;
		_cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	DFS::initdist(1);
	DFS::dfs(1,0);
	int A=DFS::farest;
	DFS::initdist(A);
	DFS::dfs(A,0);
	int B=DFS::farest;
	cout<<DFS::dist[B]<<'\n';
	//cout<<"A="<<A<<" B="<<B<<endl;
	DFS::getmid(A);
	int p1=DFS::p1,p2=DFS::p2;
	if(p1==p2)
	{
		int ans=2;
		int hdist=DFS::dist[B]/2;
		DFS::initdist(p1);
		DFS::dfs(p1,0);
		for(int i=head[p1];i;i=nxt[i])
			if(DP::dfs(g[i],p1,hdist))
			{
				DP::f[p1]++;
				ans+=DP::g[g[i]];
			}
		if(DP::f[p1]>=3) cout<<'0';
		else cout<<ans;
	}
	else
	{
		//cout<<"mid is between "<<DFS::p1<<" and "<<DFS::p2<<endl;
		int Ap1=DFS::dist[p1];
		DFS::initdist(B);
		DFS::dfs(B,0);
		int Bp2=DFS::dist[p2];
		DFS::initdist(p1);
		DFS::dfs(p1,0);
		DP::dfs(p1,p2,Ap1);
		DFS::initdist(p2);
		DFS::dfs(p2,0);
		DP::dfs(p2,p1,Bp2);
		cout<<1+DP::g[p1]+DP::g[p2];
	}
	return 0;
}

开O2是70分,没过200000的点;不开是40分,100000和200000都过不了,所以我觉得是常数的问题,但是不知道还有什么地方可以优化

2025/2/8 14:24
加载中...