简单题

本文探讨了一种特殊类型的无向图——美丽仙人掌图的生成问题。具体而言,文章介绍了一个算法,用于确定给定无向图能生成的最大美丽仙人掌图中的边数。美丽仙人掌图是一种特殊的连通无向图,每条边至多包含在一个简单环中,并且满足特定路径条件。文章详细解释了如何通过并查集和贪心策略来解决这个问题。

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

题目描述
dzy 手上有一张n 个点m 条边的联通无向图,仙人掌是一张每条边最多在一个简单环内的联通无向图。他想求这个无向图的生成仙人掌中最多有多少条边。
但是dzy 觉得这个问题太简单了,于是他定义了“美丽的生成仙人掌”,即在一个生成仙人掌中如果满足对于任意编号为ij(i<j) 的两点,存在一条它们之间的简单路径上面有ji+1 个点,则这个仙人掌是美丽的。
他现在想要知道这张图的美丽的生成仙人掌中最多有多少条边,你能帮帮他吗?
输入
第一行两个整数n,m。接下来m 行每行两个整数ui,vi,表示这两个点之间有一条无向边。保证图中没有自环。
输出
仅一行一个整数表示答案。
样例输入
2 1
1 2
样例输出
1
提示
【数据规模和约定】

对于10% 的数据,n <=10。

对于30% 的数据,n <=10^3。

对于100% 的数据,n <=10^5,m <= 2n。

第一次接触仙人掌。。。一开始凭借以前的粗略了解,以为是数据结构。。。好吧事实证明我还是too young too simple.
首先,一个没有环的美丽仙人掌肯定是这样的:
12345...n(-表示有边相连)
这样才能满足ij间简单路径必须有j-i+1个点的条件。
然后因为每条边只能在一个环内,假设这条链的区间为[l,r],那么仙人掌剩下的边肯定是[l,r]间互不交叉的边。(可以画图模拟一下,交叉的话就有两个环了)
这样问题就变成了,给你m条边,使它先形成数条链,然后在各条链中添加最多的互不交叉的边(这显然可以用贪心做)。
但是怎么找链呢?我们可以用并查集把同一条链上的点合并起来。
p[i]i
s[i]i

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,x,y,u,v,tot,ans;
struct ty
{
    int a,b;
}e[200005];
int f[100005],p[100005],s[100005];
int get(int x)
{
    if(f[x]==x) return x;else return f[x]=get(f[x]);
}
bool cmp(ty x,ty y)
{
    return x.b<y.b;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++) 
    {
        scanf("%d%d",&x,&y);
        if(x>y) swap(x,y);
        if(y-x!=1) 
        {
            tot++;
            e[tot].a=x;
            e[tot].b=y;
        }
        else
        {
            u=get(x);
            v=get(y);
            if(v!=u) //合并左右端点相邻的边
            {
                f[v]=u;
                s[u]=s[u]+s[v]+1;
                s[v]=0;
            }
        }
    }   
    if(tot>0) 
    {
        sort(e+1,e+tot+1,cmp);
        x=0;
        for(int i=1;i<=tot;i++) 
        {
            u=get(e[i].a);
            v=get(e[i].b);
            if(u==v&&e[i].a>=p[u]) //该边左右端点必须在同一集合内
            {
                s[u]++;
                p[u]=e[i].b;
            }
        }       
    }
    for(int i=1;i<=n;i++) ans=max(ans,s[i]);
    cout<<ans;
    return 0;
}
好的,我很乐意为您解释"简单管理系统"的业务用例图。 一个简单的试管理系统的业务用例图通常包含以下主要元素: 1. 系统界: 用一个大矩形表示整个系统。 2. 参与者(Actor): 表示与系统交互的外部实体,通常用人形图标表示。对于试管理系统,主要的参与者可能是: - 教师 - 学生 - 管理员 3. 用例(Use Case): 表示系统提供的功能,用椭圆形表示。可能的用例包括: - 创建试 - 编辑试 - 删除试 - 搜索试 - 查看试 - 导出试 - 导入试 - 生成试卷 - 提交答案 - 评分 4. 关关系: 用线连接参与者和用例,表示它们之间的交互。 5. 包含关系: 用带箭头的虚线连接用例,表示用例之间的包含关系。 6. 泛化关系: 用带空心箭头的实线连接用例,表示用例之间的继承关系。 一个简化的示例图可能如下: ``` +---------------------+ | 简单管理系统 | +---------------------+ | | | / \ \ / \ \ +------+ +-------+ +------+ | 教师 | | 学生 | | 管理员| +------+ +-------+ +------+ | | | | | | +------+-----+ +---+---+ +---+---+ | | | | | | v v v v v v [创建试] [编辑试] [搜索试] [查看试] [生成试卷] | | | | | | +-----+--+---------+ | v [导出试] [导入试] [提交答案] [评分] ``` 这个用例图展示了试管理系统的主要功能和参与者。教师可以创建、编辑和删除试;学生可以搜索和查看试,并提交答案;管理员可以生成试卷、导出和导入试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值