• 【BZOJ-2503】相框 并查集 + 分类讨论


    2503: 相框

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 71  Solved: 31
    [Submit][Status][Discuss]

    Description

           P大的基础电路实验课是一个无聊至极的课。每次实验,T君总是提前完成,管理员却不让T君离开,T君只能干坐在那儿无所事事。
           先说说这个实验课,无非就是把几根导线和某些元器件(电阻、电容、电感等)用焊锡焊接起来。
           为了打发时间,T君每次实验做完后都在焊接一些诡异的东西,这就是他的杰作:

     

           T君不满足于焊接奇形怪状的作品,强烈的破坏欲驱使他拆掉这个作品,然后将之焊接成规整的形状。这会儿,T君正要把这个怪物改造成一个环形,当作自己的相框,步骤如下:

     

    T君约定了两种操作:

    1.      烧熔一个焊点:使得连接在焊点上的某些导线相分离或保持相连(可以理解为:把焊点上的导线划分为若干个类,相同类中的导线相连,不同类之间的导线相离)

    2.      将两根导线的自由端(即未与任何导线相连的一端)焊接起来。

    例如上面的步骤中,先将A点烧熔,使得导线1与导线2、4点分离;再将D点烧熔,使得4、5与3、7相离;再烧熔E,使7与6、8相离;最后将1、7相连。

    T君想用最少的操作来将原有的作品改造成为相框(要用上所有的导线)。

    Input

    输入文件的第一行共有两个整数nm — 分别表示原有的作品的焊点和导线的数量 (0 ≤ n ≤ 1 000, 2 ≤ m ≤ 50 000)。焊点的标号为1~n。 接下来的m行每行共有两个整数 — 导线两端所连接的两个焊点的标号,若不与任何焊点相连,则将这一端标号为0。

    原有的作品可能不是连通的。

    某些焊点可能只有一根导线与之相连,在该导线的这一端与其他导线相连之前,这些焊点不允许被烧熔。

    某些焊点甚至没有任何导线与之相连,由于T君只关心导线,因此这些焊点可以不被考虑。

    Output

           输出文件只包含一个整数——表示T君需要将原有的作品改造成相框的最少步数。

    Sample Input

    6 8
    1 2
    1 3
    3 4
    1 4
    4 6
    5 6
    4 5
    1 5

    Sample Output

    4

    HINT

    30%的数据中n≤10。

    100%的数据中n≤1000。

    Source

    2011福建集训

    Solution

    想法很不错的一道题

     答案和每个熔点的度数有关,显然最后情况是:所有边在一个连通块,且每个熔点的度=2

    那么显然对于一个熔点,如果度数为0,显然可以扔掉;如果它的度数>2那么显然需要把他熔断,拆成很多小熔点,并且保证这些新的熔点<=2(优先=2,如果有剩余则=1),

    然后我们就需要把各连通块合并,考虑两种情况:

    1.所有边都在一个连通块中,那么我们只需要把度为1的新熔点两两合并。(最终期望合并成环)

    2.所有边不都在一个连通块中,那这两个连通块一定都被熔合成链,然后把这些链熔合成大环

    而第二种情况,就是使第一种情况的成环的成链,所以特殊处理一下

    这里需要注意一下顺序:“我们要标记1是否拆分了点,因为如果拆分过点的话我们还可以拆分成两个度为1的点,和一堆度为2的点,这只用了一次操作,如果我们后拆的话会多一次操作,注意这里即可。 ”

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    using namespace std;
    int main()
    {
        srand(time(0));
        freopen("2503data.out","w",stdout);
        int N=rand()%1000+1,M=rand()%50000+N;
        printf("%d %d
    ",N,M);
        for (int i=1; i<=M; i++)
            {
                int u=rand()%N+1,v=rand()%N;
                while (v==u) v=rand()%N;
                printf("%d %d
    ",u,v); 
            } 
        return 0;
    }
    数据生成器
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    inline int read()
    {
        int x=0; char ch=getchar();
        while (ch<'0' || ch>'9') {ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x;
    }
    #define MAXN 200010 
    int N,M;
    int fa[MAXN],size[MAXN],d[MAXN];
    inline int F(int x) {if (fa[x]==x || fa[x]==0) return fa[x]=x; else return fa[x]=F(fa[x]);}
    inline void Merge(int x,int y) {if (F(x)!=F(y)) fa[F(x)]=F(y);}
    inline int GetNum() {int re=0; for (int i=1; i<=N; i++) if (F(i)==i && d[i]) re++; return re;}
    bool vis[MAXN],mark[MAXN];//vis表示这个连通块是否需要合成链,mark表示这个连通块是否进行过拆分
    int main()
    {
        N=read(),M=read();
        int t=0,ans=0;//t记录熔点个数
        for (int i=1; i<=M; i++)
            {
                int u=read(),v=read();
                if (!u) u=++N; d[u]++; 
                if (!v) v=++N; d[v]++;  
                Merge(u,v);
            }    
        int num=GetNum();
        for (int i=1; i<=N; i++)
            if (d[i])
                {
                    if (d[i]&1) t++,vis[F(i)]=1;
                    if (d[i]>2) ans++,mark[F(i)]=1;
                }
        for (int i=1; i<=N; i++)
            if (d[i] && i==F(i) && !vis[i] && num>1)
                {
                    t+=2;
                    if (!mark[i]) ans++;
                }
        ans+=t>>1; 
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Android添加横线和竖线分割界面
    ViewPager + Fragment实现滑动标签页
    fragment中嵌套viewpager,vierpager中有多个fragment,不显示 .
    Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View
    Android SDK快速下载
    Codeforces Round #256 (Div. 2) D. Multiplication Table
    UITabBarControler解决旋转问题
    SQL Server 板机
    nested push animation can result in corrupted navigation bar
    10.树和树店
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5850953.html
Copyright © 2020-2023  润新知