Codeforces Round #237 (Div. 2)__Restore Graph

题目链接

  • 题目大意:
    给定某个点到所有点的最短距离构造这个图。要求每个点的度不能大于k
  • 分析:
    只用构造出这样的图即可。不妨把点按照度排序:度为零的在第一层,度为一的在第二层,以此类推。那么考虑一下k层和k+1层,只要k+1层的每个点都有一条来自k层的边即可。考虑每个点度的限制,那么可以贪心一下,k层的每个点只与k-1层连了一条边,那么k层的每个点还可以连k-1条边;如果k+1层的点数不超过之前一层的k-1倍就可以。特殊:对于第一层的点,因为是第一层之前没有边,所以是k倍;第一层只能有一个度为零的点
  • 注意:
    涉及到乘法,注意超int
const int MAXN = 1000100;

vector<int> vt[MAXN];
typedef pair<int, int> pii;
vector<pii> ans;

int main()
{
//    freopen("in.txt", "r", stdin);
    int n, k, t;
    while (~RII(n, k))
    {
        int Max = -INF;
        REP(i, MAXN) vt[i].clear();
        ans.clear();
        FE(i, 1, n)
        {
            RI(t);
            Max = max(Max, t);
            vt[t].push_back(i);
        }
        if (vt[0].size() != 1)
            puts("-1");
        else
        {
            if (Max >= 1 && vt[1].size() > k)
            {
                puts("-1");
                goto end;
            }
            FF(i, 0, Max)
            {
                int cur = vt[i].size();
                int next = vt[i + 1].size();
                if (i != 0 && next > (LL)(k - 1) * cur)
                {
                    puts("-1");
                    goto end;
                }
                REP(j, next)
                    ans.push_back(MP(vt[i][j % cur], vt[i + 1][j]));
            }
            cout << ans.size() << endl;
            REP(i, ans.size())
                cout << ans[i].first << ' ' << ans[i].second << endl;
        }
        end:;
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值