Codeforces Round #250 (Div. 2)补题

B:

#include<bits/stdc++.h>
#define N 100010
#define int long long
using namespace std;

int limit,sum;
//int lowb[N];
struct node{
	int lowb;
	int yuan;
}shu[N];

inline cmp(node a,node b)
{
	return a.lowb>b.lowb;
}

//signed getzhi(int a)
//{
//	int num=1;
//	if(a==2)
//		return 1;
//	while(pow(2,num)<a)
//	{
//		num++;
//	}
//	return num;
//}

int getlow (int x) {
	int c = 0;
	while (x) {
		if (x&1)
			return 1<<c;
		x /= 2;
		c++;
	}
	return 0;
}
signed main()
{
	cin>>sum>>limit;
	for(int i=1;i<=limit;i++)
		shu[i].yuan=i;
	for(int i=1;i<=limit;i++)
	{
//		if(i%2==1)
//			shu[i].lowb=1;
//		else
//		{
//			int t=getzhi(i);
//			if(pow(2,t)==i)
//				shu[i].lowb=i;
//			else
//				shu[i].lowb=i-pow(2,t);
//		}
		shu[i].lowb=getlow(i);
	}
	sort(shu+1,shu+1+limit,cmp);
	
	int zhi=limit;
	int size=0;
	int ans[N];
	
//	while(zhi)
//	{
//		if(shu[zhi].lowb<=sum)
//		{
//			sum-=shu[zhi].lowb;
//			size++;
//			ans[size]=shu[zhi].yuan;
//		}
//		zhi--;
//	}
//	if(sum)
//		cout<<"-1"<<endl;
//	else
//	{	
//		cout<<size<<endl;
//		cout<<ans[1];
//		for(int i=2;i<=size;i++)
//		{
//			cout<<" "<<ans[i];
//		}
//		cout<<endl;
//	}
	int cnt=0;	
	for(int i=1;i<=limit;i++)
	{
		if(sum>=shu[i].lowb)
		{
			sum-=shu[i].lowb;
			ans[++cnt]=shu[i].yuan;
		}
	}
	if(sum)
		cout<<"-1"<<endl;
	else{
		cout<<cnt<<endl;
		cout<<ans[1];
		for(int i=2;i<=cnt;i++)
			cout<<" "<<ans[i];
		cout<<endl;
	}
	return 0;
}

D:

#include<bits/stdc++.h>
#define N 100010
#define int long long
using namespace std;
struct node{
	int l,r;
	int minn;
}rope[N];
int n,m;
int a[N];

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<=m;i++)
	{
		int l,r;
		cin>>l>>r;
		rope[i].l=a[l];
		rope[i].r=a[r];
		rope[i].minn=min(rope[i].l,rope[i].r);
	}
	int sum=0;
	for(int i=1;i<=m;i++)
	{
		sum+=rope[i].minn;
	}
	cout<<sum<<endl;
	return 0;
}

D:并查集(巧妙)

#include<bits/stdc++.h>
#define int long long
#define N 100010

using namespace std;
int num[N];
int p[N];
struct node{
	int l,r;
	int minn;
}e[N];

int find(int x)
{
	if(p[x]!=x)
		p[x]=find(p[x]);
	return p[x];
}

bool cmp(node a,node b){
	return a.minn>b.minn;
}
int n,m;
int a[N];
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		p[i]=i;
		num[i]=1;
	}
		
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<=m;i++)
	{
		cin>>e[i].l>>e[i].r;
		e[i].minn=min(a[e[i].l],a[e[i].r]);
	}
	sort(e+1,e+1+m,cmp);
	int ans=0;
	for(int i=1;i<=m;i++)
	{
		int aa=find(e[i].l);
		int bb=find(e[i].r);
		//已经排过序了,所以每次新取得边都比之前的边要小
		//所以不用再更新区间的最小值了
		if(aa!=bb)
		{//因为现在的最小边乘上点的个数==现在这个点可以和多少个点构成联系
			ans+=num[aa]*num[bb]*e[i].minn;
			p[aa]=bb;
			num[bb]+=num[aa];
		}
	}
	cout<<setprecision(6)<<ans*2.0/(n*(n-1))<<endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值