清真的構造題ios
UOJ# 460git
求將$ n$個點的徹底圖劃分紅最多的生成樹的數量,並輸出一種構造方案spa
首先一棵生成樹有$ n-1$條邊,而原徹底圖只有$\frac{n·(n-1)}{2}$條邊code
於是最多的生成樹數量僅爲$\frac{n}{2}$blog
只考慮$ n$爲偶數的狀況(n爲奇數時全部生成樹中隨便挑一個點往新點連邊便可)get
當$n=2$時生成樹爲(1,2)string
當$ n >2$時先將$ n$和$ n-1$連邊it
而後將對於$ 1 \leq i <n-1$,若是$ i$是奇數就將$ (i,n)$加入$ n$所在的生成樹,將$ (i,n-1)$加入$ i$所屬的生成樹io
不然將$ (i,n)$加入$ i$所屬的生成樹,將$ (i,n-1)$加入$ n$所屬的生成樹class
這樣就構造完畢了
#include<ctime> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> #define rt register int #define ll long long using namespace std; inline ll read(){ ll x=0;char zf=1;char ch=getchar(); while(ch!='-'&&!isdigit(ch))ch=getchar(); if(ch=='-')zf=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf; } void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);} void writeln(const ll y){write(y);putchar('\n');} int k,m,n,x,y,z,cnt,ans; void print(int x,int y){ write(x);putchar(' ');write(y);putchar(' '); } int main(){ n=read(); writeln(n/2); for(rt i=1;i+1<=n;i+=2){ print(i,i+1); for(rt j=1;j<i;j++)if(j&1)print(i,j);else print(i+1,j); for(rt j=i+2;j<=n;j++)if(j&1)print(i+1,j);else print(i,j); putchar('\n'); } return 0; }