题目大意
给你一个 n n n 个点的完全图 n n n 为奇数,让你划分为 k k k 条长度为 a i a_i ai 且不相交的路径,输出这 k k k 条路径。
解题思路
在完全图上构造
(
n
−
1
)
/
2
(n-1)/2
(n−1)/2 个不同的长度为
n
n
n 的欧拉回路。
完全图每个顶点的度数一定为偶数,每构造一个欧拉回路之后每个点的度仍然为偶数,所以一定可以构造出来这样的欧拉回路,构造出来之后就按顺序输出即可。
这里提供一种构造方法,至于为什么会想到不必深究。
由于点数是奇数,所以我们首先将最大的点选出来,然后对于前
(
n
−
1
)
/
2
(n-1)/2
(n−1)/2 个点,我们让每个点作为起点
i
i
i,每次将最大点连上起点,然后每次连的点,坐标变化为
+
1
,
−
2
,
+
3
,
−
4
,
⋯
,
−
(
n
−
1
)
+1, -2, +3, -4, \cdots, -(n-1)
+1,−2,+3,−4,⋯,−(n−1),这样的话会恰好构造出一个欧拉回路,且每次构造的欧拉回路不会重复。
Code
#include <bits/stdc++.h>
#define ll long long
#define qc ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define fi first
#define se second
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define pb push_back
using namespace std;
const int MAXN = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int n, m;
int a[MAXN];
void solve(){
cin >> n >> m;
for (int i = 1; i <= m; ++i){
cin >> a[i];
}
vector<int> v;
int mod = n-1;
for (int i = 0; i < n/2; ++i){
v.pb(n-1);
int now = i;
for (int j = 1; j <= n-1; ++j){
v.pb(now);
now += j & 1 ? j : -j;
now = (now % mod + mod) % mod;
}
}
v.pb(n-1);
int cnt = 0;
for (int i = 1; i <= m; ++i){
int k = a[i]+1;
while(k--) cout << v[cnt++]+1 << " \n"[k==0];
cnt--;
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
qc;
int T;
cin >> T;
//T = 1;
int cnt = 0;
while(T--){
cout << "Case #" << ++cnt << ":\n";
solve();
}
return 0;
}