码迷,mamicode.com
首页 > 其他好文 > 详细

基环树

时间:2020-12-01 12:29:19      阅读:7      评论:0      收藏:0      [点我收藏+]

标签:pre   int   oid   dfs   node   struct   else   class   ++   

基环树

基环树直径

P3248

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
int n;
int te,v[N<<1],pre[N<<1],tail[N];
ll L,len=2e18,w[N<<1],dis[N],d[N<<1];
int tak[N],c[N<<1];
bool vis[N];

inline void add(int x,int y,int z)
{
	v[++te]=y;w[te]=(ll)z;pre[te]=tail[x];tail[x]=te;
}

void Dfs(int x,int fa)
{
	vis[x]=1;tak[++tak[0]]=x;
	for(int i=tail[x];i&&!c[0];i=pre[i])
	if(v[i]!=fa)
	{
		if(!vis[v[i]]) Dfs(v[i],x);
		else
		{
			while(tak[tak[0]]!=v[i]) c[++c[0]]=tak[tak[0]--];
			c[++c[0]]=v[i];
		}
	}
	tak[0]--;
}

void dfs(int x)
{
	vis[x]=1;
	for(int i=tail[x];i;i=pre[i])
	if(!vis[v[i]])
	{
		dfs(v[i]);
		L=max(L,dis[x]+dis[v[i]]+w[i]);
		dis[x]=max(dis[x],dis[v[i]]+w[i]);
	}
}
ll calc(int x,int y)
{
	return dis[c[x]]-d[x]+dis[c[y]]+d[y];
}

struct node1
{
	int x;
	friend bool operator<(node1 a,node1 b)
	{
		return dis[c[a.x]]-d[a.x]<dis[c[b.x]]-d[b.x];
	}
};
struct node2
{
	int x;
	friend bool operator<(node2 a,node2 b)
	{
		return dis[c[a.x]]+d[a.x]<dis[c[b.x]]+d[b.x];
	}
};
priority_queue<node1>q1;
priority_queue<node2>q2;

void work()
{
	for(int i=1;i<=n;++i) vis[i]=0;
	for(int i=1;i<=c[0];++i) vis[c[i]]=1;
	for(int i=1;i<=c[0];++i) dfs(c[i]);
	
	int tmp=c[0];
	for(int i=1;i<=tmp;++i) c[++c[0]]=c[i];
	for(int i=2;i<=c[0];++i)
	for(int j=tail[c[i]];j;j=pre[j])
	if(v[j]==c[i-1]){d[i]=d[i-1]+w[j];break;}
	
	for(int i=1;i<=tmp;++i) 
	q1.push((node1){i}),q2.push((node2){i});
	
	for(int i=1;i<=tmp;++i)
	{
		while(q1.size()>1&&q1.top().x<i) q1.pop();
		while(q2.size()>1&&q2.top().x<i) q2.pop();
	
		int x=q1.top().x,y=q2.top().x;
		if(x==y)
		{
			q1.pop();q2.pop();
			
			while(q1.size()>1&&q1.top().x<i) q1.pop();
			while(q2.size()>1&&q2.top().x<i) q2.pop();
	
			int xx=q1.top().x,yy=q2.top().x;
			len=min(len,max(calc(x,yy),calc(xx,y)));
			
			q1.push((node1){x}),q2.push((node2){y});
		}
		else len=min(len,calc(x,y));
		
		q1.push((node1){tmp+i}),q2.push((node2){tmp+i});
	}
	len=max(len,L);
}

int main()
{
	scanf("%d",&n);
	for(int i=1,x,y,z;i<=n;++i) scanf("%d %d %d",&x,&y,&z),add(x,y,z),add(y,x,z);
	Dfs(1,0);work();
	printf("%.1lf",0.5*len);
}

基环树

标签:pre   int   oid   dfs   node   struct   else   class   ++   

原文地址:https://www.cnblogs.com/anliaoran/p/14044589.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!