首页 > 其他 > 详细

Codeforces Round #237 (Div. 2)__Restore Graph

时间:2014-03-23 15:57:44      阅读:392      评论:0      收藏:0      [点我收藏+]

题目链接

  • 题目大意:
    给定某个点到所有点的最短距离构造这个图。要求每个点的度不能大于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;
}


Codeforces Round #237 (Div. 2)__Restore Graph,布布扣,bubuko.com

Codeforces Round #237 (Div. 2)__Restore Graph

原文:http://blog.csdn.net/wty__/article/details/21871987

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!