codeforces+D. Maximum Diameter Graph+给定 点的度数 构造(最大直径树)

本文介绍了一种算法,用于解决给定顶点最大度数时构造一棵树的问题,目标是使树的直径最大化。通过将度数大于1的顶点连成链,并将度数为1的顶点优先连接到链的两端,最终实现树的构造。文章包含了详细的算法思路和C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值