题意:给出n,k,要求构造出n个点的无向带权图,满足:最小和最大生成树是唯一的,并且最小和最大生成树正好有k条公共边.
n,k<=1e5,边数不超过2*n.无解输出-1.
若C(n,2)<(n-1)*2-k 则边数不够,无解.
生成树唯一,最简单就是每条边权值都不同.
先考虑0条公共边的情况:1-2-..n连接权值为[1.n-1]的边. 1-3-5-..n 2-4-6-..n-1 .(id为两组中其中一个点)id-n连接权值为[n,2*n-1]
n,k<=1e5,边数不超过2*n.无解输出-1.
若C(n,2)<(n-1)*2-k 则边数不够,无解.
生成树唯一,最简单就是每条边权值都不同.
先考虑0条公共边的情况:1-2-..n连接权值为[1.n-1]的边. 1-3-5-..n 2-4-6-..n-1 .(id为两组中其中一个点)id-n连接权值为[n,2*n-1]
现在有k条公共边 只要让[n-k..n]这k条边为公共边.令m=n-k [1..m]的边,如k=0方法构造即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll n,k;
int main()
{
cin>>n>>k;
if(n*(n-1)/2<(n-1)*2-k)
{
puts("-1");
return 0;
}
int m=n-k,num=2*(n-1)-k,off=n;
printf("%d\n",num);
for(int i=1;i<n;i++)
printf("%d %d %d\n",i,i+1,i);
for(int i=1;i+2<=m;i+=2)
printf("%d %d %d\n",i,i+2,off+i);
for(int i=2;i+2<=m;i+=2)
printf("%d %d %d\n",i,i+2,off+i);
int id=2;
if(m%2==0)
id--;
printf("%d %d 1234567\n",id,n);
return 0;
}