https://codeforces.com/problemset/problem/404/C
题意翻译
对于n个顶点,我们对其进行加边操作!
首先题目会给你n,k 再给n个数 第 i 个为d_idi,就是从某一点开始的到i的最短路。 我们对其加边使其满足这最后的答案,如果不能满足,就是输出-1
一个顶点的度 应该不大于 k Translated by @Bartholomew
输入输出样例
输入 #1复制
3 2 0 1 1
输出 #1复制
3 1 2 1 3 3 2
输入 #2复制
4 2 2 0 1 3
输出 #2复制
3 1 3 1 4 2 3
输入 #3复制
3 1 0 0 0
输出 #3复制
-1
思路:把长度为1,2,3......的分别存到队列和vector<int>mp[maxn]的桶里,然后对当前长度i的结点进行遍历,如果上一层(i-1)的队里不空并且那个的degree[]<k,那么连边存下来,不然就把这个点弹出来。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
struct node{
LL x,y;
}nodes[maxn];
queue<LL> q[maxn];
vector<LL> mp[maxn];
LL deg[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n,k;cin>>n>>k;
LL flag=0;
for(LL i=1;i<=n;i++){
LL _x;cin>>_x;
if(_x==0) flag++;
q[_x].push(i);
mp[_x].push_back(i);
}
if(flag>=2){
cout<<"-1"<<endl;return 0;
}
LL cnt=0;
for(LL i=1;i<=n;i++){
for(LL j=0;j<mp[i].size();j++){
LL u=-1;
LL v=mp[i][j];
while(!q[i-1].empty())
{
u=q[i-1].front();
if(deg[u]<k) break;
else q[i-1].pop();
}
if(u!=-1&°[u]<k)
{
deg[u]++;
deg[v]++;
nodes[++cnt].x=u;
nodes[cnt].y=v;
}
else{
cout<<"-1"<<endl;
return 0;
}
}
}
cout<<cnt<<endl;
for(LL i=1;i<=cnt;i++){
cout<<nodes[i].x<<" "<<nodes[i].y<<endl;
}
return 0;
}