Codeforces Round #237 (Div. 2) C

C. Restore Graph

Valera had an undirected connected graph without self-loops and multiple edges consisting ofn vertices. The graph had an interesting property: there were at mostk edges adjacent to each of its vertices. For convenience, we will assume that the graph vertices were indexed by integers from 1 ton.

One day Valera counted the shortest distances from one of the graph vertices to all other ones and wrote them out in arrayd. Thus, element d[i] of the array shows the shortest distance from the vertex Valera chose to vertex numberi.

Then something irreparable terrible happened. Valera lost the initial graph. However, he still has the arrayd. Help him restore the lost graph.

Input

The first line contains two space-separated integers n andk (1 ≤ k < n ≤ 105). Numbern shows the number of vertices in the original graph. Numberk shows that at most k edges were adjacent to each vertex in the original graph.

The second line contains space-separated integers d[1], d[2], ..., d[n](0 ≤ d[i] < n). Number d[i] shows the shortest distance from the vertex Valera chose to the vertex numberi.

Output

If Valera made a mistake in his notes and the required graph doesn't exist, print in the first line number -1. Otherwise, in the first line print integerm (0 ≤ m ≤ 106) — the number of edges in the found graph.

In each of the next m lines print two space-separated integersai andbi(1 ≤ ai, bi ≤ nai ≠ bi), denoting the edge that connects vertices with numbers ai andbi. The graph shouldn't contain self-loops and multiple edges. If there are multiple possible answers, print any of them.

Sample test(s)
Input
3 2
0 1 1
Output
3
1 2
1 3
3 2
Input
4 2
2 0 1 3
Output
3
1 3
1 4
2 3
Input
3 1
0 0 0
Output
-1

 点击打开链接   题目连接

题意:给出n个节点和一个数k,然后是其他个节点到其中一个节点的距离的一个数组,d[i]表示i节点到选定节点的距离,这个选点的节点到自身的距离就是0,需要我们自己找到选定的节点,不满足(多于一个选定的节点)这个条件输出-1,如果可以建图,当某一个节点的度数大于k时也输出-1,当某个节点自身有自环,也输出-1,否则,输出m对节点x, y,表示x和y之间有一条边。

我的方法就是先判断d[i]==0的个数,如果个数不等于1的话那么此图就不存在,存在的话(等于1)就按照到节点i(d[i]==0)的距离排序,距离为d+1的肯定连接到距离为d的节点上,然后依次建立图,并存到邻接表,最后对每个节点判断是否有环或者有超过k的边数



#include <cstdio>
#include <set>
#include <iostream>
#include <string>
#include <queue>
#include <cstring>
#include <algorithm>
#define LL long long
#define Inf (1<<30)
#define MOD 1000000007
#define M 1000010
#define Max(x,y) (x)>(y)?(x):(y)
#define Min(x,y) (x)>(y)?(y):(x)
using namespace std;
struct node
{
	int p,v;
}a[M];
int vis[M];
int n,k;
vector<int>res[M];
bool cmp(node x,node y)
{
	return x.v<y.v;
}
int main()
{	
	int i,j,k,o=1,m;
	int maxn=Inf;
	//freopen("D:\\o.txt","r",stdin);
	while(~scanf("%d%d",&n,&k))
	{
		int ok=0,cnt=0;
		memset(vis,0,sizeof(vis));
		for(i=0;i<n;i++)res[i].clear();
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i].v);
			if(a[i].v==0)cnt++;
			a[i].p=i+1;
		}
		sort(a,a+n,cmp);
		if(cnt!=1)puts("-1");
		else {
			int x=0,y=1,v=1,tot=0;//x,y保存距离为v+1的节点的下标编号
			memset(vis,0,sizeof(vis));
			for(i=1;i<n;)
			{
				j=x;
				while(i<n&&a[i].v==v)
				{
					if(j>=y)j=x;
					//printf("%d %d\n",a[j].p,a[i].p);
					res[a[j].p].push_back(a[i].p);
					vis[a[j].p]++;vis[a[i].p]++;
					if(vis[a[j].p]>k||vis[a[i].p]>k||a[i].p==a[j].p)ok=1;//比赛的时候少了这里的一个判断条件,结果一直错
					tot++;
					j++;i++;
				}
				x=y;
				y=i;
				v++;
			}		
			if(ok)puts("-1");
			else {
				printf("%d\n",tot);
				for(i=0;i<=n;i++)
				{
					if(res[i].size()>0)
					{
						for(j=0;j<res[i].size();j++)
							printf("%d %d\n",i,res[i][j]);
					}
				}
			}
		}
	}
    return 0;
}








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值