求最小权值和,选择的是前 2n 个小的值。配对的时候一定是选出的这 2n 个值中最小坐标点和最大坐标点进行配对,次小坐标点和次大坐标点进行配对……建立一个结构体将坐标值,权值,编号区分开,然后先对整体按权值排序,再对前 2n 个点按坐标值排序,这样就可以直接进行配对并输出对应的点的编号了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200005;
struct node
{
int x,w,id;
}a[N];
bool cmp1(node a,node b){
return a.w<b.w;
}
bool cmp2(node a,node b)
{
return a.x<b.x;
}
int main()
{
int t;cin>>t;
while(t--)
{
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a[i].x>>a[i].w;
a[i].id=i;
}
sort(a+1,a+1+m,cmp1);
sort(a+1,a+2*n+1,cmp2);
ll sum=0;
for(int i=1;i<=2*n;i++) sum+=a[i].w;
cout<<sum<<endl;
for(int i=1;i<=n;i++)
{
cout<<a[i].id<<' '<<a[2*n-i+1].id<<endl;
}
cout<<endl;
}
return 0;
}