• 仙人掌(cactus)


    仙人掌(cactus)


    Time Limit:1000ms Memory Limit:64MB


    题目描述


    LYK 在冲刺清华集训(THUSC) !于是它开始研究仙人掌,它想来和你一起分享它最近
    研究的结果。


    如果在一个无向连通图中任意一条边至多属于一个简单环 (简单环的定义为每个点至多
    经过一次) ,且不存在自环,我们称这个图为仙人掌。
    LYK 觉得仙人掌还是太简单了,于是它定义了属于自己的仙人掌。
    定义一张图为美妙的仙人掌, 当且仅当这张图是一个仙人掌且对于任意两个不同的点 i,j,
    存在一条从 i 出发到 j 的路径,且经过的点的个数为|j-i|+1 个。
    给定一张 n 个点 m 条边且没有自环的图,LYK 想知道美妙的仙人掌最多有多少条边。


    数据保证整张图至少存在一个美妙的仙人掌。


    输入格式(cactus.in)


    第一行两个数 n,m 表示这张图的点数和边数。
    接下来 m 行,每行两个数 u,v 表示存在一条连接 u,v 的无向边。


    输出格式(cactus.out)


    一个数表示答案


    输入样例


    4 6
    1 2
    1 3
    1 4
    2 3
    2 4
    3 4


    输出样例


    4


    样例解释


    选择边 1-2,1-3,2-3,3-4,能组成美妙的仙人掌,且不存在其它美妙仙人掌有超过 4 条
    边。


    数据范围


    对于 20%的数据 n<=3。
    对于 40%的数据 n<=5。
    对于 60%的数据 n<=8。
    对于 80%的数据 n<=1000。
    对于 100%的数据 n<=100000 且 m<=min(200000,n*(n-1)/2)。

    思路:

      仙人掌可以简化为一个线段覆盖问题

      说白了就是每个点只能被一条线段覆盖(不包括线段两边的点)

      不能被更多的线段覆盖

      所以我们可以在预处理所有的边后进行一次贪心取边

      来,上代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    struct node {
        int from,to;
    };
    struct node edge[300001];
    
    int n,m,num=0,pd[200001],jkl;
    int from,to,tmp,ans=0,cur=-1;
    
    char ch;
    
    void qread(int &x)
    {
        x=0,jkl=1;ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')jkl=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+(int)(ch-'0');ch=getchar();}
        x*=jkl;
    }
    
    void edge_add(int from,int to)
    {
        num++;
        edge[num].to=to;
        edge[num].from=from;
    }
    
    bool cmp1(struct node a,struct node b){return a.from>b.from;}
    
    bool cmp(struct node a,struct node b){return a.to<b.to;}
    
    int main()
    {
        qread(n),qread(m);
        for(int i=1;i<=m;i++)
        {
            qread(from),qread(to);
            if(from>to) tmp=from,from=to,to=tmp;
            //if(pd[to]==0&&from==to-1) ans++,pd[to]=1;
            //else edge_add(from,to);
            if(from+1==to) continue;
            edge_add(from,to);
        }
        sort(edge+1,edge+num+1,cmp1);
        sort(edge+1,edge+num+1,cmp);
        for(int i=1;i<=num;i++)
        {
            if(edge[i].from>=cur)
            {
                cur=edge[i].to;
                ans++;
            }
        }
        cout<<ans+n-1<<endl;
        return 0;
    }
  • 相关阅读:
    计算机网络-数据结构-MAC帧头-IP头-TCP头-UDP头
    (考研)java网络编程
    多态(重点:方法的多态性和对象的多态性)
    JZOJ1497 景点中心 题解
    JZOJ1227 Coprime 题解
    JZOJ3966 Sabotage 题解
    JZOJ3056 数字 题解
    JZOJ3054 祖孙询问 题解
    【Luogu P2282】【JZOJ 4906】【NOIP2016提高组复赛】组合数问题 题解
    JZOJ4316【NOIP2015模拟11.5】Isfind 题解
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6046323.html
Copyright © 2020-2023  润新知