zoukankan      html  css  js  c++  java
  • bzoj 2503 相框——思路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2503

    我也知道应该只关注度数。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1005,M=50005;
    int n,m,deg[N],sum,ans;
    int main()
    {
        scanf("%d%d",&n,&m);int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            deg[x]++;deg[y]++;
            sum+=(!deg[x])+(!deg[y]);//焊接 
        }
        for(int i=1;i<=n;i++)
        {
            if(deg[i]>1)ans+=deg[i]/2-1+(deg[i]&1);//烧熔 
            sum+=(deg[i]&1);//焊接 
        }
        printf("%d",ans+(sum>>1));
        return 0;
    }
    秒WA

    应该仔细读题,那个不用deg[ i ]/2 - 1 + (deg[ i ] & 1),一次就能焊好;

    而且还没管不同连通块。

    TJ:http://www.cnblogs.com/TSHugh/p/7617699.html

    需要记一下一个连通块里有没有奇度数的点,因为对于没有的要手动熔断。这时要特判是不是只有一个连通块。

    学习TJ代码:https://blog.csdn.net/PoPoQQQ/article/details/48031135

    终于发现一次就能把一个点熔好了。还记录了一个连通块有没有被熔过。就因为一次也能顺便熔出两个奇度数点,所以对于没有奇度数点的连通块要通过这个判断是否需要再熔一次。

    还学习了TJ的好写法:读入的时候不用区分0的端点什么的,++n就好了!仔细想一想是等价的。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1005,M=5e4+5;
    int n,m,deg[N],fa[N],jd,ans,yf,cnt;
    bool tag[N],cz[N];
    int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
    int main()
    {
        scanf("%d%d",&n,&m);int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if(!x)x=++n;if(!y)y=++n;//!!!
            deg[x]++;deg[y]++;fa[find(x)]=find(y);
    //      if(!x&&!y)jd+=2;
    //      else if(x&&y)deg[x]++,deg[y]++,fa[find(x)]=find(y);
    //      else{
    //          jd++;if(x)deg[x]++;if(y)deg[y]++;
    //      }
        }
        for(int i=1;i<=n;i++)
        {
            if(deg[i]&1)jd++,tag[find(i)]=1;
            if(deg[i]>2)ans++,cz[find(i)]=1;//记录cz!//一次就能熔好!!!!! 
            if(deg[i]&&fa[i]==i)cnt++;//deg[i]!!
        }
        if(cnt==1&&!jd){printf("0
    ");return 0;}
        for(int i=1;i<=n;i++)
            if(fa[i]==i&&!tag[i]&&cnt>1)
            {
                if(!cz[i])ans++;
                jd+=2;//&&cnt>1!
            }
        printf("%d
    ",ans+(jd>>1));
        return 0;
    }
    秒WA

    再次学习(抄)了一遍。

    别忘了到处判断deg[ i ]!!!别忘了把数组调大,赋 fa[ ] 的时候也要调大范围!

    虽然A了可是一点也不高兴怎么办……

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1005,M=5e4+5,Lm=1e5+1e3+5;;
    int n,m,deg[Lm],fa[Lm],jd,ans,cnt;
    bool tag[Lm],cz[Lm];
    int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
    int main()
    {
        scanf("%d%d",&n,&m);int x,y;
        for(int i=1;i<=Lm-5;i++)fa[i]=i;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if(!x)x=++n;if(!y)y=++n;//!!!
            deg[x]++;deg[y]++;fa[find(x)]=find(y);
    //      if(!x&&!y)jd+=2;
    //      else if(x&&y)deg[x]++,deg[y]++,fa[find(x)]=find(y);
    //      else{
    //          jd++;if(x)deg[x]++;if(y)deg[y]++;
    //      }
        }
        for(int i=1;i<=n;i++)
        {
            if(deg[i]&1)jd++,tag[find(i)]=1;
            if(deg[i]>2)ans++,cz[find(i)]=1;//记录cz!//一次就能熔好!!!!! 
            if(deg[i]&&find(i)==i)cnt++;//deg[i]!!
        }
    //  if(cnt==1&&!jd){printf("0
    ");return 0;}
        for(int i=1;i<=n;i++)
            if(deg[i]&&find(i)==i&&!tag[i]&&cnt>1)//deg[i]!!!
            {
                if(!cz[i])ans++;
                jd+=2;//&&cnt>1!
            }
        printf("%d
    ",ans+(jd>>1));
        return 0;
    }
  • 相关阅读:
    在mvc4中上传、导入和导出excel表方法总结
    ASP.NET MVC:通过 FileResult 向 浏览器 发送文件
    .net下使用NPOI读取Excel表数据
    详解免费高效实用的.NET操作Excel组件NPOI(转)
    Vue 定时执行函数
    decorators.xml的用法
    行内元素和块级元素
    C/C++中printf和C++中cout的输出格式
    IIS 搭建过程
    IIS访问共享文件详解
  • 原文地址:https://www.cnblogs.com/Narh/p/9282557.html
Copyright © 2011-2022 走看看