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