codeforces+D. Maximum Diameter Graph+给定 点的度数 构造(最大直径树)
题目链接:http://codeforces.com/problemset/problem/1082/D
题目大意:
给你n个顶点
给定这n个顶点的的最大度数 ,让你构造一棵树,使得直径最大。
如果不能构造树,删除NO,如果能,输出YES 最大直径,和每条边
三个顶点:
度数最大为2,2,2
思路:
如果总度数>(n-1)*2则可以构造。
构造方法:把度数>1的顶点连成一条链,再把其余的度数为1的比优先连接到链的起点和终点。再连接到其他点。
思考:第一次构造这种树的题,也算是熟练了一下吧。
#include<bits/stdc++.h>
using namespace std;
int e[505];
vector<int> v;
vector<int> p;
int main()
{
fill(e, e+505, 0);
int n, x;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&e[i]);
ans+=e[i];
if(e[i]!=1)
v.push_back(i);/*度数为1的顶点*/
else
p.push_back(i);/*度数为1的顶点*/
}
if(ans<(n-1)*2)
{
cout<<"NO"<<endl;
}
else
{
int s=v.size()-1;
s+=min(2, n-(const int)v.size());
cout<<"YES"<<' '<<s<<endl;
cout<<n-1<<endl;
for(int i=0;i<v.size()-1;i++)/*把度数>1的顶点连成一条链*/
{
cout<<v[i]<<' '<<v[i+1]<<endl;
}
/*处理度数为1的点*/
if(p.size()==1)
{
cout<<p[0]<<' '<<v[0]<<endl;
p.erase(p.begin());
}
else if(p.size()>=2)
{
cout<<p[0]<<' '<<v[0]<<endl;
cout<<p[1]<<' '<<v[v.size()-1]<<endl;
p.erase(p.begin());
p.erase(p.begin());
while(p.size())
{
for(int i=0;i<v.size();i++)
{
for(int j=e[v[i]];j>2;j--)
{
cout<<p[0]<<' '<<v[i]<<endl;
p.erase(p.begin());
if(p.size()==0)
{
return 0;
}
}
}
}
}
}
return 0;
}