Codeforces - Maximum Diameter Graph

题目链接:Codeforces - Maximum Diameter Graph


显然只需要构成一棵树是最优的。

如果没有度为1的话,那么直接构成一条链即可。

如果度为1的只有1个或者2个,还是可以把这度为1的节点放到叶子,构成一条链。

否则有多个度不为1 的点。不管这个些点怎么放,因为边是固定的,所以总度数之和也是固定的,可以用来判断是否合法。

如果合法就直接让度为1的点找空位放。(首尾优先)。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=510;
int n,cnt,mx,num,pos;
struct node{int d,id;}t[N];
vector<pair<int,int>> res,v;
int cmp(node a,node b){return a.d>b.d;}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)	cin>>t[i].d,t[i].id=i;
	sort(t+1,t+1+n,cmp);
	if(t[1].d==1)	return puts("NO"),0;
	if(t[n].d>1){
		cout<<"YES"<<' '<<n-1<<endl<<n-1<<endl;
		for(int i=1;i<n;i++)	cout<<i<<' '<<i+1<<endl;	return 0;
	}
	for(int i=1;i<=n;i++){
		if(t[i].d==1){cnt=n-i+1;	pos=i;	mx=i-1;	break;}
		num+=t[i].d;	if(i!=1)	res.push_back({t[i].id,t[i-1].id});
		v.push_back({t[i].d,t[i].id});
	}
	int sz=v.size();	if(!pos)	pos=n+1;
	if(sz==2)	num-=2;
	else if(sz>2)	num-=(sz-1)*2;
	if(cnt>num)	return puts("NO"),0;
	printf("YES ");	cout<<mx+min(2,cnt)-1<<endl;
	cout<<n-1<<endl;	int p=0;
	for(int i=0;i<res.size();i++)	cout<<res[i].first<<' '<<res[i].second<<endl;
	if(pos==n+1)	return 0;
	for(int i=0;i<v.size()&&v.size()>1;i++)	v[i].first-=2;
	if(pos==n)	return cout<<v[0].second<<' '<<t[pos].id<<endl,0;	
	cout<<t[pos].id<<' '<<v[0].second<<endl;
	cout<<t[pos+1].id<<' '<<v[v.size()-1].second<<endl;	pos+=2;
	for(int i=pos;i<=n;i++){
		if(v[p].first==0)	p++;
		cout<<t[i].id<<' '<<v[p].second<<endl;	v[p].first--;
	}
	return 0;
}
发布了604 篇原创文章 · 获赞 242 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104405798