让你构造一个图,然后最小生成树的边要是给定的边
第一次没靠题解做出来d题
然后按照克鲁斯卡尔的思路想了一发
发现构造成一条链就好了。。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct rec
{
int x,y,v,biao,wei;
}bian[301000];
bool cmp(rec a,rec b)
{
if (a.v!=b.v) return a.v<b.v;
return a.biao>b.biao;
}
bool cmp2(rec a,rec b) {return a.wei<b.wei;}
int n,m;
int main()
{
freopen("test.in","r",stdin);
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&bian[i].v,&bian[i].biao);
bian[i].wei=i;
}
sort(bian+1,bian+m+1,cmp);
if (((long long)n*(long long)(n-1)/2)<m)
{
printf("-1");
return 0;
}
for (long long i=m,tot1=m,tmp=0,start_x=n,start_y=1,tot2=n;i;i--)
{
if (bian[i].biao==1)
{
if (((tot2-2)*(tot2-1)/2)>=tot1-tmp-1)
{
tot1=tot1-tmp-1;
bian[i].x=tot2;
bian[i].y=tot2-1;
if (start_x==tot2)
{
start_x=tot2-1;
start_y=1;
}
tot2--;
tmp=0;
}
else
{
printf("-1");
return 0;
}
}
else
{
if (start_x==start_y+1)
{
start_x--;
start_y=1;
}
bian[i].x=start_x;
bian[i].y=start_y;
start_y++;
tmp++;
}
}
sort(bian+1,bian+m+1,cmp2);
for (int i=1;i<=m;i++)
printf("%d %d\n",bian[i].x,bian[i].y);
return 0;
}