Codeforecs 550D Regular Bridge (神奇的构造题)

本文介绍了一种算法,用于构造一个无向图,其中每个顶点的度数固定,且图中包含恰好一个桥。文章详细阐述了算法的逻辑与实现,并附带完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


发觉自己水平越来越烂真是一件悲伤的事。。

要好好加油了


题意

         给定一个k(1<=k<=100),要求求出一张无向图,这张无向图的每个顶点度数都是k(有k条边和这个顶点相连),而且无向图至少要有一个桥(求出的无向图只能有一个连通块)。

         割顶/关节点:在连通图中,去掉一个顶点,能让这张图不再全连通(变成两个连通块)。

         桥:在连通图中,去掉一条边,能让这张图不再全连通(变成两个连通块)。


思路

下面我们来考虑图中只有一个桥的情况(好吧只需要考虑这个)。

我们可以想当然的认为构造出来的图是这样的:假设我们的图中一共有2n+4(为什么这样一会儿会解释)个顶点,则每边的顶点个数应该为n+2,同时每一侧有一个顶点和另外一侧相连(形成桥),因此构造的图可以是对称的,只要考虑一边就好了。


图的总度数为(2n+4)*k,总边数(也相当于一侧的度数)为(n+2)*k。


若不考虑中间相连的边,则左侧的度数为(n+2)*k-1。

1.当k为偶数时, (n+2)*k-1,一定是奇数,而一个连通图不可能度数为奇数,因此k为偶数时全部是NO。

2.下面考虑k为奇数的情况,由于每个顶点的度数要求为k,所以该顶点必须和k个顶点相连,考虑单独一侧,则该侧至少要k+1个顶点。但是如果一侧只有(k+1)个顶点,那么(k+1)*k-1依然是奇数,所以至少要有(k+2)个顶点(当然k+4也是可以的)。

 

确定了每边的顶点数后,下面我们来考虑如何构造。

意淫过程参考自:http://blog.youkuaiyun.com/codebattle/article/details/46383049


首先,1号顶点(桥的一侧)需要和k-1个顶点相连,此时这k-1个顶点每个还差k-1度,我们让他们互相连接,此时这k-1个顶点还差1度。


引入第k+1号顶点,让他去和这k-1个顶点相连,此时前k个顶点满足条件,第k+1号顶点还差1度,因此再引入第k+2号顶点,与第k+1号相连。


此时所有顶点中,只有第k+2号还差k-1度,我们可以想办法让2-k号各下降1度,然后让他们与第k+2号相连。


由于k是奇数,因此2-k共有偶数个顶点,这些顶点是互相连接的,具体的做法可以是,删除2-3,4-5,6-7…(k-1)-(k)之间的边,这样2-k号各下降1度。



说了这么多,其实编程实现并不复杂(可能我水平比较烂的关系),需要注意的是:推导的过程中我们每条边都考虑了两次,但是只需要输出一次。

 

假设顶点有n+2个

1号:与2-n相连

2-n号:若x为偶数,则x与 x+2到n+2所有顶点相连,若x为奇数,则x与 x+1到n+2所有顶点相连.

n+1号:与n+2连一条边.


这样一侧就构造完了,另外一侧完全相同(只要加上n+2的偏移量即可)。



最后不要忘了连上两侧的连线,而且对于1的情况要特判(表示当时完全没注意这点)

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

const int maxn=1e5+50;
const int INF=0x3f3f3f3f;

int k;
void print(int n,int base)
{
    for (int i=2;i<=n-2;i++){
        printf("%d %d\n",1+base,i+base);
    }
    for (int i=2;i<=n-2;i++){
        for (int j=i+1;j<=n;j++){
            if (j==i+1 && i%2==0) continue;
            printf("%d %d\n",i+base,j+base);
        }
    }
    printf("%d %d\n",n-1+base,n+base);
}
void solve(){
     if (k==1){
         printf("2 1\n1 2\n");
         return;
     }
    int n=(k+2)*2,m=(k+2)*k,base=k+2;
    printf("%d %d\n",n,m);
    print(k+2,0);
    print(k+2,base);
    printf("%d %d\n",1,k+3);
}
int main()
{
    #ifndef ONLINE_JUDGE
       // freopen("in.txt","r",stdin);
    #endif

    while(scanf("%d",&k)!=EOF){
        if (k&1){
            puts("YES");
            solve();
        }else puts("NO");
    }


    return 0;
}


 

 


1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值