---
显然 构图后,Exit-nodes必须连接到度为1的点上 使得那n-k个非Exit-nodes的点度>=2
不难发现 度为1的点尽可能多,最远的2个Exit-nodes距离就越短
而Exit-nodes只有k,即度=1的点<=k个
选出一个中心点,给它k条边连接到其他点,形成一个周期为k的圆,不停绕着圆连点即可
#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<list>
#define ll long long
#define pii pair<int,int>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int inf=0x3f3f3f3f;
const int N = 2e5+5;
int num[N];//圆上i位置的链上的元素个数
int now[N];//现在圆上i位置上最外面的点是now[i]
int outD[N];//第i个Exit-nodes的深度
void slove(int n,int k){
vector<pii>ans;
MEM(num,0);
int idx=0;
int a=n-k;
int center=a-1;
for(int i=0;i<k;++i){
now[i]=center;
}
int i;
for(i=0;i<center;++i){
ans.push_back({now[i%k],i});
now[i%k]=i;
++num[i%k];
}
for(int j=0;j<k;++j){
ans.push_back({now[(i+j)%k],i+1+j});
now[(i+j)%k]=i+1+j;
++num[(i+j)%k];
outD[j]=num[(i+j)%k];
}
sort(outD,outD+k,greater<int>());
printf("%d\n",outD[0]+outD[1]);
for(int i=0;i<ans.size();++i){
printf("%d %d\n",ans[i].first+1,ans[i].second+1);
}
}
int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
int n,k;
while(~scanf("%d%d",&n,&k)){
slove(n,k);
}
return 0;
}