社区讨论

奇怪的问题,求解

P2619[国家集训队] Tree I参与者 2已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lodfmxci
此快照首次捕获于
2023/10/31 05:49
2 年前
此快照最后确认于
2023/11/06 21:06
2 年前
查看原帖
RT
CPP
inline bool check(int val) {
	rep(i,1,n) f[i]=i;tot=num=cnt=sum=0;
	R int i=1,j=1;
	while(i<=nb&&j<=nh) {
		if(b[i].val+val<h[j].val) e[++tot]=b[i++];
		else e[++tot]=h[j++];
	}
	while(i<=nb) e[++tot]=b[i++];
	while(j<=nh) e[++tot]=h[j++];
	rep(i,1,m) {
		int u=e[i].from,v=e[i].to,w=e[i].val,c=e[i].col;
		int r1=find(u),r2=find(v);
		if(r1==r2) continue ;
		f[r1]=r2,++cnt,sum+=w+(!e[i].col)*val;
		if(!c) ++num;
		if(cnt==n-1) break ;
	}
	return num<=need;
}
CPP
inline bool check(int val) {
	rep(i,1,n) f[i]=i;tot=num=cnt=sum=0;
	R int i=1,j=1;
	while(i<=nb&&j<=nh) {
		if(b[i].val+val<h[j].val) e[++tot]=b[i++]+val;
		else e[++tot]=h[j++];
	}
	while(i<=nb) e[++tot]=b[i++];
	while(j<=nh) e[++tot]=h[j++];
	rep(i,1,m) {
		int u=e[i].from,v=e[i].to,w=e[i].val,c=e[i].col;
		int r1=find(u),r2=find(v);
		if(r1==r2) continue ;
		f[r1]=r2,++cnt,sum+=w;
		if(!c) ++num;
		if(cnt==n-1) break ;
	}
	return num<=need;
}
个人认为这两种写法应该是等价的,但似乎第二种过不了
另外还有一个问题
就是在归并排序的时候,如果在新的数组里不加上当前需要判断的val,在最后计算时也不减去val×need,为什么也是错的呢(有个同学觉得这是因为val可能加了超过need次,但在我的代码中是这样的:
CPP
while(l<=r) {
	int mid=(l+r)>>1;
	if(check(mid)) now=mid,r=mid-1;
	else l=mid+1;
}
check(now);
printf("%d",sum-need*now);
我认为这样在最后一次check的时候加入的白边数量一定为need,所以在最后一次check(now)的时候这样应该不会错吧。
求助qwq

回复

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

正在加载回复...