2021杭电多校第六场 1004——Decomposition

题目大意

给你一个 n n n 个点的完全图 n n n 为奇数,让你划分为 k k k 条长度为 a i a_i ai 且不相交的路径,输出这 k k k 条路径。

解题思路

在完全图上构造 ( n − 1 ) / 2 (n-1)/2 (n1)/2 个不同的长度为 n n n 的欧拉回路。
完全图每个顶点的度数一定为偶数,每构造一个欧拉回路之后每个点的度仍然为偶数,所以一定可以构造出来这样的欧拉回路,构造出来之后就按顺序输出即可。
这里提供一种构造方法,至于为什么会想到不必深究。
由于点数是奇数,所以我们首先将最大的点选出来,然后对于前 ( n − 1 ) / 2 (n-1)/2 (n1)/2 个点,我们让每个点作为起点 i i i,每次将最大点连上起点,然后每次连的点,坐标变化为 + 1 , − 2 , + 3 , − 4 , ⋯   , − ( n − 1 ) +1, -2, +3, -4, \cdots, -(n-1) +1,2,+3,4,,(n1),这样的话会恰好构造出一个欧拉回路,且每次构造的欧拉回路不会重复。

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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值