社区讨论

lca死循环求助

P4180[BJWC2010] 严格次小生成树参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lobp9cmc
此快照首次捕获于
2023/10/30 00:42
2 年前
此快照最后确认于
2023/11/04 05:23
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int xl(int x)
{
	if(x&1) return x+1;
	else return x-1;
}
int n,m;
struct lsqxx
{
	struct ee
	{
		int next;
		int to;
		bool can;
		int val;
	};
	int head[maxn],cnt;
	ee bb[maxn*6];
	lsqxx()
	{
		memset(head,0,sizeof head);
		cnt=0;
	}
	void jb(int q,int z,int v)
	{
		bb[++cnt].to=z;
		bb[cnt].val=v;
		bb[cnt].can=0;
		bb[cnt].next=head[q];
		head[q]=cnt;
	}
};
lsqxx b1;
struct bcj
{
	int fa[maxn];
	void init()
	{
		for(int i=1;i<=n;i++)
			fa[i]=i;
	}
	int cz(int x)
	{
		int r=x;
		while(fa[x]!=x) x=fa[x];
		return fa[r]=x;
	}
	bool hb(int x,int y)
	{
		x=cz(x),y=cz(y);
		if(fa[x]==fa[y]) return 0;
		fa[x]=y;
		return 1;
	}
};
bcj bc;
struct eb
{
	int q;
	int z;
	int val;
	int cnt;
	bool can;
	eb()
	{
		q=z=val=0;can=0;
	}
	eb(int _q,int _z,int _v)
	{
		q=_q,z=_z,val=_v;can=0;
	}
	friend bool operator <(eb a,eb b)
	{
		return a.val<b.val;
	}
};
struct zxscs
{
	eb ed[maxn];
	int solve()
	{
		sort(ed+1,ed+1+n);
		int ans=0;
		for(int i=1;i<=m;i++)
		{
			eb t=ed[i];
			if(bc.hb(t.q,t.z)==0)
				b1.bb[t.cnt].can=1,b1.bb[t.cnt+1].can=ed[i].can=1,ans+=ed[i].val;
		}
		return ans;
	}
};
zxscs sc;
struct spp
{
	int fa[maxn],lfa[maxn],size[maxn],son[maxn];
	int top[maxn],mp[maxn],sd[maxn];
	void init()
	{
		memset(mp,0,sizeof mp);
		memset(son,0,sizeof son);
	}
	void dfs(int x,int f,int ss)
	{
		fa[x]=f;size[x]=1;sd[x]=ss;
		for(int i=b1.head[x];i;i=b1.bb[i].next)
		{
			int sx=b1.bb[i].to;
			if(b1.bb[i].can&&sx!=f)
			{
				dfs(sx,x,ss+1);lfa[sx]=b1.bb[i].val;
				size[x]=size[sx]+size[x];
				if(size[sx]>size[son[x]])
					son[x]=sx;
			}
		}
	}
	void dfs2(int x)
	{
		if(x==son[fa[x]])
			top[x]=top[fa[x]],mp[top[x]]=max(mp[top[x]],lfa[x]);
		else top[x]=x;
		if(son[x])
			dfs2(son[x]);
		for(int i=b1.head[x];i;i=b1.bb[i].next)
		{
			int sx=b1.bb[i].to;
			if(sx!=son[x]&&sx!=fa[x])
				dfs2(son[x]);
		}
	}
	int lca(int x,int y)
	{
		while(top[x]!=top[y])
		{
			if(sd[top[x]]<sd[top[y]]) swap(x,y);
			x=fa[top[x]];
		}
		if(sd[x]<sd[y]) swap(x,y);
		return x;
	}
	int cz(int x,int y)
	{
		int t=lca(x,y);cout<<1;
		int ans=0;
		if(top[x]==top[t])
		{
			while(x!=t)
			{
				ans=max(ans,lfa[x]);
				x=fa[x];
			}
		}
		else
		{
			while(x!=top[x])
			{
				ans=max(ans,lfa[x]);
				x=fa[x];
			}
			while(top[fa[x]]!=top[t])
			{
				ans=max(ans,max(lfa[x],mp[fa[x]]));
				x=fa[top[x]];
			}
			while(x!=t)
			{
				ans=max(ans,lfa[x]);
				x=fa[x];
			}
		}
		if(top[y]==top[t])
		{
			while(y!=t)
			{
				ans=max(ans,lfa[y]);
				y=fa[y];
			}
		}
		else
		{
			while(y!=top[y])
			{
				ans=max(ans,lfa[y]);
				y=fa[y];
			}
			while(top[fa[y]]!=top[t])
			{
				ans=max(ans,max(lfa[y],mp[fa[y]]));
				y=fa[top[y]];
			}
			while(y!=t)
			{
				ans=max(ans,lfa[y]);
				y=fa[y];
			}
		}
		return ans;
	}
};
spp sp;
int main()
{
	scanf("%d%d",&n,&m);
	bc.init();
	sp.init();
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&sc.ed[i].q,&sc.ed[i].z,&sc.ed[i].val);
		sc.ed[i].cnt=i*2-1;
		b1.jb(sc.ed[i].q,sc.ed[i].z,sc.ed[i].val);
		b1.jb(sc.ed[i].z,sc.ed[i].q,sc.ed[i].val);
	}
	int maxz=sc.solve();//cout<<maxz;
	sp.dfs(1,1,1);
	sp.dfs2(1);
	int min1=INT_MAX,min2=INT_MAX;
	for(int i=1;i<=m;i+=2)
	{
		eb w=sc.ed[i];
		if(w.can==0)
		{
			int mq=maxz-sp.cz(w.q,w.z)+w.val;
			if(mq<=min2)
				min2=mq;
			else if(mq<min2)
				min2=min1,min1=mq;
		}
	}
	if(min1!=maxz) printf("%d",min1);
	else printf("%d",min2);
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...