题目链接: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;
}