岛屿
求基环树直径
未完成 挖坑
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define ll long long
#define fs first
#define sc second
#define mp make_pair
using namespace std;
const int N=1e6+10;
const int M=N*2;
int read()
{
int x=0,f=0,c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return f?-x:x;
}
struct Edge
{
int to,next,w;
}e[M];
int head[N],cnt=1;
void _add(int a,int b,int c){ e[++cnt]=(Edge){b,head[a],c}; head[a]=cnt;}
void add(int a,int b,int c){ _add(a,b,c); _add(b,a,c); }
bool vis[N],onr[N];
int ring[N],tot,top,n;
ll dis[N],ans,ret,a[N*2],sum,d[N];
pair<int,long long> sta[N];
ll getdis(int x,int y)
{
if(x>y) swap(x,y);
if(y<=tot) return dis[y]-dis[x];
return sum-(dis[y-tot]-dis[x]);
}
void dfs(int x,int ine)
{
sta[++top]=mp(x,e[ine].w); vis[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(i==(ine^1)) continue;
if(!vis[y]) dfs(y,i);
else
{
int tmp=e[i].w;
for(int t=sta[top].fs;t!=x;t=sta[--top].fs)
{
onr[t]=1,ring[++tot]=t;
dis[tot+1]=dis[tot]+sta[top].sc; sum+=sta[top].sc;
}
onr[x]=1;ring[++tot]=x;dis[tot+1]=dis[tot]+tmp;sum+=tmp;
}
}
top--;
}
void dp(int x,int ff)
{
vis[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(onr[y]||y==ff) continue;
dp(y,x);
ret=max(ret,d[x]+d[y]+e[i].w);
d[x]=max(d[x],d[y]+e[i].w);
}
}
deque<int> q;
int D(int x)
{
dfs(x,0);
for(int i=1;i<=tot;i++) dp(ring[i],0);
for(int i=1;i<=tot;i++) a[i]=a[i+tot]=d[ring[i]];
q.push_back(1);
for(int i=2;i<=tot+sum/2;i++)
{
while(q.size()&&getdis(ring[i],ring[q.front()])>sum/2) q.pop_front();
ret=max(ret,a[i]+a[q.front()]+getdis(ring[i],ring[q.front()]));
while(q.size()&&a[i]-i>a[q.back()]-q.back()) q.pop_back();
}
return ret;
}
int main()
{
n=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read(),z=read();
add(x,y,z);
}
for(int i=1;i<=n;i++)
if(!vis[i]) ans+=D(i);
printf("%d",ans);
}

浙公网安备 33010602011771号