zoukankan      html  css  js  c++  java
  • Codeforces 1082D Maximum Diameter Graph

    Codeforces Tutorial

    D. Maximum Diameter Graph

    Problem Analysis

    构造一个简单图,要求每个节点的度$ le a_i$,并且图的直径最大。

    构造过程分为两步:

    1. 用所有(a_i gt 1)的节点构造一条直链(L)
    2. 将剩余的(a_i = 1)的节点从(L)两端向中间添加分支

    最后的结果就是一棵树
    所以要求

    [sum_{i=1}^{n}a_i ge 2(n-1) ]

    Acepted Code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<istream>
    #include<cassert>
    #include<set>
    #define DEBUG(x) cout<<#x<<" = "<<x<<endl
    #define DEBUG2(x,y) cout<<#x<<" = "<<x<<" , "
    <<#y<<" = "<<y<<endl
    using namespace std;
    typedef long long ll;
    const int MAXN=600;
    int n;
    int a[MAXN];
    int main()
    {
    //    freopen("in.txt","r",stdin);
        cin>>n;
        int sum=0;
        vector<int>ones;
        for(int ii=1;ii<=n ;ii++ ){
            cin>>a[ii];
            sum+=a[ii];
            if(a[ii]==1){
                ones.push_back(ii);
                a[ii]=0;
            }
        }
        if(sum<2*n-2){
            cout<<"NO";
            return 0;
        }
        int ans=n-ones.size()-1+min(2,(int)ones.size());
        cout<<"YES "<<ans<<endl<<n-1<<endl;
        int lst=-1;
        if(!ones.empty()){
            lst=ones.back();
            ones.pop_back();
        }
        for(int ii=1;ii<=n ;ii++ ){
            if(a[ii]>1){
                if(lst!=-1){
                    a[ii]--,a[lst]--;
                    cout<<lst<<" "<<ii<<endl;
                }
                lst=ii;
            }
        }
        for(int ii=n;ii>=1 ;ii-- ){
            while (!ones.empty()&&a[ii]>0){
                a[ii]--;
                cout<<ones.back()<<" "<<ii<<endl;
                ones.pop_back();
            }
        }
    }
    
    

    Wrong Answer Cases

    What I Learn

    什么是构造(construct)?

    • 生成满足某些要求的输出

    这个构造问题的要求有以下三个:

    • 图的直径最大
    • 每个节点的度都有上限
    • 简单图

    满足要求的顺序很重要。第一个最严格,所以优先第一个条件,满足直径最大。这样一来问题就迎刃而解了。

    Reference

    https://codeforces.com/blog/entry/63544

  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/10964118.html
Copyright © 2011-2022 走看看