40pts 找不到跟我一模一样的做法 感觉是细节问题
查看原帖
40pts 找不到跟我一模一样的做法 感觉是细节问题
177604
LXH5514楼主2021/7/29 10:34

码风很丑。。。 别的好像都是将白的边加上某个值,我的是将黑边加,感觉问题不大,然后kruskal统计答案的时候,排序优先选白边,直接加上边原来的权值就行。 下了一下第 6 个数据点,发现当最终二分到 mid=-8 时 ans=22395,sum=365;当 mid=- 9时 ans=22443,sum = 359 。而答案却是 362 , 22419.。。。。

#include<bits/stdc++.h>
using namespace std;
int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c-'0'),c=getchar();
	return x*f;
}
const int MAXN=1e5+10,inf=100;
int n,m,need,mid,l,r,ans,out;
int f[MAXN];
struct node
{
	int u,v,val,p;
}d[MAXN];
bool cmp(node x,node y)
{
	if(x.val+x.p*mid==y.val+y.p*mid)return x.p<y.p;
	return x.val+x.p*mid<y.val+y.p*mid;
}
int cz(int x)
{
	if(f[x]==x)return x;
	return f[x]=cz(f[x]);
}
void hb(int x,int y)
{
	int a=cz(x),b=cz(y);
	f[a]=b; 
}
bool pd()
{
	int sum=0,cnt=n;
	ans=0;
	sort(d+1,d+1+m,cmp);
	for(int i=0;i<=n-1;i++)
	f[i]=i;
	for(int i=1;cnt>1&&i<=m;i++)
	{
		if(cz(d[i].u)!=cz(d[i].v))
		{
			hb(d[i].u,d[i].v);
			sum+=(d[i].p==0);
			cnt--;
			ans+=d[i].val;
		}
	}
	if(sum<=need)return 1;
	return 0;
}
int main()
{
	n=read();
	m=read();
	need=read();
	for(int i=1;i<=m;i++)
	{
		d[i].u=read();
		d[i].v=read();
		d[i].val=read();
		d[i].p=read(); 
	}
	l=-inf,r=inf;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(pd())out=ans,l=mid+1;
		else r=mid-1;
	}
	printf("%d\n",out);
 	return 0;
}
2021/7/29 10:34
加载中...