🐝 🐝 🐝
给出n个点的度数上限,求能构造出的直径最长的图
(1)把所有度数大于等于2 的拿出来构造一条链
(2)剩下的度数为1的点挨个往链上放
(3)无法构造的情况就是度数全部为1(此时要排除n=1的情况),或者存在点没地安排
int n;
int nxt[1111];//保存链的信息
int du[1111];//某点的剩余度数
vector<pii>edge;//答案的边
vector<int>v,vv;//存下度数为1/度数大于等于2的点
signed main()
{
cin>>n;
rpp(i,n)
{
int x;cin>>x;du[i]=x;
if(x==1) v.push_back(i);
else vv.push_back(i);
}
if(n==1)
{
cout<<"YES 1"<<endl;
cout<<0<<endl;
return 0;
}
if(sz(vv)==0)
{
cout<<"NO\n";
return 0;
}
int pre=vv[0],ans=0;
for(int i=1;i<sz(vv);++i)
{
edge.push_back(make_pair(pre,vv[i]));
--du[pre],--du[vv[i]],nxt[pre]=vv[i],++ans;
pre=vv[i];
}
int flag=2;
for(auto x:v)
{
if(flag==2) edge.push_back(make_pair(x,vv[0])),--du[vv[0]],--flag,++ans;
else if(flag==1) edge.push_back(make_pair(pre,x)),--du[pre],--flag,++ans;
else
{
int can=0;
for(int j=vv[0];;j=nxt[j])
{
if(du[j]>0)
{
--du[j],can=1,edge.push_back(make_pair(j,x));
break;
}
if(j==pre) break;
}
if(!can)
{
cout<<"NO\n";
return 0;
}
}
}
cout<<"YES "<<ans<<endl;
cout<<sz(edge)<<endl;
for(auto x:edge) cout<<x.first<<" "<<x.second<<endl;
stop;
return 0;
}