一个神奇的问题
查看原帖
一个神奇的问题
112738
zzy_123楼主2021/11/13 19:49
		if(sum[a].val+x<=sum1[b].val)
		{
			p[e]=sum[a];a++;
			p[e].val+=x;
		}

上面为在归并时加上mid

		if(p[a].si==0)
		j++,d+=x;

上面为统计时再加上mid 为什么第一种65分第二种AC. 下面为AC代码

#include<stdio.h>
#include<stdlib.h>
typedef struct zzy
{
	int u,v,val,next,si;
}zzy;
zzy sum1[101010],sum[101010],p[101010];
int n,m,head[101010],s,head1[101010],len,len1,ans=0,f[101010],ans1;
void add(int u,int v,int val)
{
	sum[++len].v=v;
	sum[len].u=u;
	sum[len].next=head[u];
	head[u]=len;
	sum[len].val=val;
	sum[len].si=0;
}
void add1(int u,int v,int val)
{
	sum1[++len1].v=v;
	sum1[len1].u=u;
	sum1[len1].next=head1[u];
	head1[u]=len1;
	sum1[len1].val=val;
	sum1[len1].si=1;
}
int cmp(void const *x,void const *y)
{
	zzy *a=(zzy *)x;
	zzy *b=(zzy *)y;
	if(a->val>b->val)return 1;
	else return -1;
}
int cmp1(void const *x,void const *y)
{
	zzy *a=(zzy *)x;
	zzy *b=(zzy *)y;
	if(a->val>b->val)return 1;
	else return -1;
}
int find(int x)
{
	if(f[x]==x)return x;
	f[x]=find(f[x]);
	return f[x];
}
int prime(int x)
{
	int a=1,b=1,c,d=0,e=1,j=0,l=0;ans1=0;
	while(a<=len&&b<=len1)
	{
		if(sum[a].val+x<=sum1[b].val)
		{
			p[e]=sum[a];a++;
//			p[e].val+=x;
		}else
		{
			p[e]=sum1[b];b++;
		}
		e++;
	}e--;
	while(a<=len)
	p[++e]=sum[a++];
	while(b<=len1)
	p[++e]=sum1[b++];
	for(a=0;a<=n;a++)f[a]=a;
	for(a=1;a<=e;a++)
	{
		int u=p[a].u,v=p[a].v;
		u=find(u);v=find(v);
		if(u==v)continue;
		f[v]=f[u];
		if(p[a].si==0)
		j++,d+=x;
		d+=p[a].val;
		l++;
		if(l==n-1)break;
	}ans1=d;
	return j;
}
int main()
{
	int a,b,c,d,e;
	scanf("%d%d%d",&n,&m,&s);
	for(a=1;a<=m;a++)
	{
		scanf("%d%d%d%d",&b,&c,&d,&e);
		if(e==0)
		{
			add(b,c,d);
		}else
		{
			add1(b,c,d);
		}
	}
	int mid,l=-150,r=150;
	qsort(sum+1,len,sizeof(zzy),cmp);
	qsort(sum1+1,len1,sizeof(zzy),cmp1);
	while(l<=r)
	{
		mid=(l+r)/2;
		b=prime(mid);
		if(b>=s)
		{
			ans=ans1-s*mid;	
			l=mid+1;
		}else r=mid-1;	
	}
	printf("%d",ans);
} 
2021/11/13 19:49
加载中...