奇怪思路95求助
查看原帖
奇怪思路95求助
234582
zpl__hhd楼主2021/5/3 10:41
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+5,maxm=5e4+5;
int n,m,q,cnt,ct;
struct edge
{
	int t,next,w,f;
}e[maxm<<1],c[maxm<<1];
int head[maxn],head2[maxn],d[maxn],lg[maxn],w[maxn][15];
inline void add(int f,int t,int w)
{
	e[++cnt].t=t;
	e[cnt].f=f;
	e[cnt].w=w;
	e[cnt].next=head[f];
	head[f]=cnt;
}
inline void add2(int f,int t,int w)
{
	c[++ct].t=t;
	c[ct].w=w;
	c[ct].next=head2[f];
	head2[f]=ct;
}
bool cmp(edge a,edge b)
{
	return a.w>b.w;
}
int f[maxn],fa[maxn][15];
int find(int x)
{
	if(f[x]==x)return x;
	else return f[x]=find(f[x]);
}
void dfs(int x,int fath,int v)
{
	fa[x][0]=fath;d[x]=d[fath]+1;w[x][0]=v;
	
	for(int i=1;i<=lg[d[x]];i++)
	{
		fa[x][i]=fa[fa[x][i-1]][i-1];
		w[x][i]=min(w[x][i-1],w[fa[x][i-1]][i-1]);
	}
	
	for(int i=head2[x];i;i=c[i].next)
	if(c[i].t!=fath)dfs(c[i].t,x,c[i].w);
}
int lca(int u,int v)
{
	int ans=0x3f3f3f3f;
	if(d[u]>d[v])swap(u,v);
	while(d[u]<d[v])
	{
		ans=min(ans,w[v][lg[d[v]-d[u]]-1]);
		v=fa[v][lg[d[v]-d[u]]-1];
	}
	if(u==v)return ans;
	for(int k=lg[d[u]]-1;k>=0;k--)
	{
		if(fa[u][k]!=fa[v][k])
		{
			ans=min(ans,w[u][k]);
			ans=min(ans,w[v][k]);
			u=fa[u][k];
			v=fa[v][k];
		}
	}
	return min(w[v][0],min(ans,w[u][0]));
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	lg[i]=lg[i-1]+(1<<lg[i-1]==i);
	for(int i=1;i<=m;i++)
	{
		int f,t,w;
		scanf("%d%d%d",&f,&t,&w);
		add(f,t,w);
		add(t,f,w);
	}
	for(int i=1;i<=n;i++)
	{add(0,i,-1);add(i,0,-1);}
	for(int i=0;i<=n;i++)f[i]=i;
	
	sort(e+1,e+cnt+1,cmp);
	
	for(int i=1;i<=cnt;i++)
	if(find(e[i].f)!=find(e[i].t))
	{
		f[find(e[i].f)]=find(e[i].t);
		add2(e[i].f,e[i].t,e[i].w);
		add2(e[i].t,e[i].f,e[i].w);
	}
	
	dfs(0,n+1,0);
	
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{
		int f,t;
		scanf("%d%d",&f,&t);
		printf("%d\n",lca(f,t));
	}
}
我的思路是:用超级根节点0,对每个点连一条限重-1的边。直接跑LCA,但WA了一个点,WA在-1.求助。。。
2021/5/3 10:41
加载中...