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\n");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\n",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\n");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\n",ans+(jd>>1));
    return 0;
}

 

posted on 2018-07-09 10:28  Narh  阅读(158)  评论(0编辑  收藏  举报

导航