萌新求助,LCA倍增+Kruskal 10分WA求助
查看原帖
萌新求助,LCA倍增+Kruskal 10分WA求助
206010
TKater_yzt楼主2021/10/19 21:38

RT,下面是程序,前两个能过,后面的下载不了了,今日次数已用完,所以不知道错误在哪地方,本地手算了几个样例都过了qwq

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;

const LL maxn=50100;
LL a[maxn],head[maxn],fa[maxn][25],lg[maxn],depth[maxn],minn[maxn][25],f[maxn];
LL n,m,p,tot,k;

struct mode{
	LL start;
	LL end;
	LL next;
	LL val;
}e[maxn<<1];

struct mode1{
	LL a;
	LL b;
	LL val;	
}q[maxn<<1];

bool cmp(mode1 a,mode1 b)
{
	return a.val>b.val;
}

inline void add(LL x,LL y,LL k)
{
	e[++tot].end=y;
	e[tot].start=x;
	e[tot].val=k;
	e[tot].next=head[x];
	head[x]=tot;
	return ;
}

inline void dfs(LL node,LL father)
{
	fa[node][0]=father;
	depth[node]=depth[father]+1;
	for(LL i=head[node];i;i=e[i].next)
	{
		if(e[i].end!=father)
		{
			minn[e[i].end][0]=e[i].val;
			dfs(e[i].end,node);
		}
	}
	for(LL i=1;i<=lg[depth[node]]-1;i++)
	{
		fa[node][i]=fa[fa[node][i-1]][i-1];
		minn[node][i]=min(minn[node][i-1],minn[fa[node][i-1]][i-1]);
	}
	return ;
}

inline LL find(LL x)
{
	if(f[x]==x)return f[x];
	f[x]=find(f[x]);
	return f[x];
}

inline void init();

inline void kruskal()
{
	LL root1,root2,cnt=0;
	init();
	sort(q+1,q+1+m,cmp);
//	printf("%lld %lld\n",q[1].a,q[1].b);
//	printf("%lld\n",m);
	for(LL i=1;i<=m;i++)
	{
//		printf("%lld %lld\n",q[i].a,q[i].b);
//		printf("**********\n");
		root1=find(q[i].a);
		root2=find(q[i].b);
		if(root1!=root2)
		{
			add(q[i].a,q[i].b,q[i].val);
			add(q[i].b,q[i].a,q[i].val);
			f[root1]=root2;
			cnt++;
//			printf("%lld %lld\n",q[i].a,q[i].b);
		}
		if(cnt==n-1)break;
	}
	return ;
}

inline void init()
{
	for(LL i=1;i<=n;i++)
	{
		f[i]=i;
	}
	return ;
}

inline LL LCA(LL a,LL b)
{
	if(find(a)!=find(b))return -1;
	LL cnt=999999999,jump_one,jump_two;
	
	if(depth[a]<depth[b])swap(a,b);
	while(depth[a]-depth[b]>0)
	{	
		cnt=min(cnt,minn[a][lg[depth[a]-depth[b]]-1]);
		a=fa[a][lg[depth[a]-depth[b]]-1];
//		printf("***%lld\n",cnt);
	}
	if(a==b)return cnt;
//	if(depth[a]==depth[b])cnt=min(minn[a][0],minn[b][0]);
	for(LL i=lg[depth[a]]-1;i>=0;i--)
	{
//		jump_one=a;
//		jump_two=b;
		if(fa[a][i]!=fa[b][i])
		{
			cnt=min(minn[a][i],cnt);
			cnt=min(minn[b][i],cnt);
//			printf("@@@%lld %lld %lld\n",minn[a][i],minn[b][i],cnt);
			a=fa[a][i];
			b=fa[b][i];
		}
	}
	cnt=min(minn[a][0],cnt);
	cnt=min(minn[b][0],cnt);
	return cnt;
}

int main()
{
	LL i,j,x,y;
	scanf("%lld %lld",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%lld %lld %lld",&x,&y,&k);
//		add(x,y,k);
//		add(y,x,k);
		q[i].a=x;
		q[i].b=y;
		q[i].val=k;
	}
	for(i=1;i<=n;i++)
	{
		lg[i]=lg[i-1]+(1<<lg[i-1]==i);
	}
	kruskal();
	minn[1][0]=-1;
	dfs(1,0);
	scanf("%lld",&p);
//	for(i=1;i<=n;i++)
//	{
//		for(j=0;j<=depth[n]-1;j++)
//		{
//			printf("%lld ",minn[i][j]);
//		}
//		printf("\n");
//	}
	for(i=1;i<=p;i++)
	{
		scanf("%lld %lld",&x,&y);
		printf("%lld\n",LCA(x,y));
	}
	return 0;
}
/*
	10 24
4 7 19038
7 10 7375
7 9 17853
9 8 6341
7 2 16976
10 3 2835
10 4 19285
9 4 29193
3 4 4852
3 8 16597
9 1 4138
9 7 21611
7 4 10586
10 4 7821
10 9 25636
3 9 28425
2 3 17229
4 8 11331
9 2 25053
6 4 929
8 3 1738
10 9 28542
1 2 28343
3 5 13215
9
7 5
2 4
10 2
5 10
7 10
4 3
10 1
10 4
8 4

13215
25053
25053
13215
21611
28425
25053
28542
16597


*/
2021/10/19 21:38
加载中...