该题主要考查图的构造,并输出相连的节点;用到的一个技巧是开一个vector<int>g[N],g[i]存的是距离为i的节点的位置;这题也有许多特判条件,需特别注意。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
const int N=2e5+20;
int a[N];
vector<int>g[N];
int main()
{
int n,m,i,j;
int ma=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i]; ma=max(ma,a[i]);
g[a[i]].push_back(i);
}
if(m<n-1)
{
cout<<-1;
return 0;
}
vector<PII>v;
for(int i=1;i<=ma;i++)
{
if(g[i].empty())
{
cout<<-1;
return 0;
}
for(auto j:g[i])
{
v.push_back({g[i-1][0],j}); //建树
}
}
if(v.size()<m){
for(int i=1;i<=ma;i++)
{
for(int j=0;j<g[i].size();j++)
{
for(int k=j+1;k<g[i].size();k++){
v.push_back({g[i][j],g[i][k]}); //树的同一层两点连接
if(v.size()==m) break;
}
if(v.size()==m) break;
}
if(v.size()==m) break;
}
for(int i=1;i<=ma;i++){
for(int j=1;j<g[i].size();j++){
for(auto k:g[i+1]){
v.push_back({g[i][j],k}); //树与下一层连接,g[i][0]点建树时已经连接过了;
if(v.size()==m) break;
}
if(v.size()==m) break;
}
if(v.size()==m) break;
}
}
if(v.size()<m)
{
cout<<-1;
return 0;
}
for(auto i:v)
{
cout<<i.first<<" "<<i.second<<'\n';
}
}