可爱萌新求调生成树
查看原帖
可爱萌新求调生成树
774854
qzmoot楼主2024/11/1 11:34
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=205,M=1e4+5,inf=1e9;
int n,m;
struct node{
	int fr,to,a,b,len;
}a[M];
bool cmp(node x,node y)
{
	return x.len<y.len;
}
struct xl{
	int x,y;
};
xl ans=(xl){inf,inf},A,B; 
bool operator<(xl i,xl j)
{
	return i.x*i.y==j.x*j.y?i.x<j.x:i.x*i.y<j.x*j.y;
}
xl operator-(xl i,xl j)
{
	return (xl){i.x-j.x,i.y-j.y};
}
int operator*(xl i,xl j)
{
	return i.x*j.y-i.y*j.x;
}
xl min(xl i,xl j)
{
	return i<j?i:j;
}
int f[N];
int find(int x)
{
	return f[x]==x?x:f[x]=find(f[x]);
}
void init()
{
	for(int i=1;i<=n;i++)
		f[i]=i;
	sort(a+1,a+1+m,cmp);
}
xl kru()
{
	init();
	int cnt=0;
	xl res=(xl){0,0};
	for(int i=1;i<=m;i++)
	{
		int fx=find(a[i].fr),fy=find(a[i].to);
		if(fx!=fy)
		{
			f[fy]=fx;
			res.x+=a[i].a;
			res.y+=a[i].b;
			cnt++;
		}
		if(cnt==n-1)
			break;
	}
	return res;
}
void solve(xl l,xl r)
{
	for(int i=1;i<=m;i++)
		a[i].len=a[i].a*(l.y-r.y)+a[i].b*(l.x-r.x);
	xl mid;
	ans=min(ans,mid=kru());
	if((r-l)*(mid-l)>=0)
		return;
	solve(l,mid);
	solve(mid,r);
}
signed main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=m;i++)
		scanf("%lld%lld%lld%lld",&a[i].fr,&a[i].to,&a[i].a,&a[i].b);
	for(int i=1;i<=m;i++)
		a[i].len=a[i].a;
	ans=min(ans,A=kru());
	for(int i=1;i<=m;i++)
		a[i].len=a[i].b;
	ans=min(ans,B=kru());
	solve(A,B);
	printf("%lld %lld",ans.x,ans.y);
	return 0;
}
2024/11/1 11:34
加载中...