CodeForces - 1082D Maximum Diameter Graph (构造,模拟,链)

本文介绍了一种算法,用于根据给定点集的度数上限构造直径最大的图。算法分为三步:首先,从所有点中筛选出度数大于等于2的点来构建链;其次,将剩余度数为1的点逐一添加到链上;最后,处理无法构造图的特殊情况,如所有点度数均为1且n不为1的情况。通过此算法,可以有效地解决构建最大直径图的问题。
摘要由CSDN通过智能技术生成

🐝 🐝 🐝
给出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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值