nyist 129(It is a tree?)

 题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=129

是不是要满足三个条件:

1、只有一个根结点,如果有多个则是森林;
2、除根结点外其他的节点入度只能是1,如有其它,则不是;
3、结点数-边数=1,主要是确保每一个节点只有一个父节点。还要注意空树也是一颗树~~

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAX=10010;
#define CLR(arr,val) memset(arr,val,sizeof(arr));//这是学的聪神的做法,呵呵呵~~他的博客是:http://blog.acmol.com~非常推荐看!!
int indgree[MAX],sign[MAX],father[MAX],rank[MAX],sum=1;
void Init()
{   for(int i=0;i<MAX;i++)
    {   father[i]=i;
        rank[i]=1;
        sign[i]=0;//标记点i是否用到 
    }
}
int Find(int u)
{   return father[u]==u?u:Find(father[u]);
}
void Union(int u,int v)
{   u=Find(u);
    v=Find(v);
    if(u==v) return ;
    if(rank[u]>rank[v]) 
    {  rank[u]+=rank[v];
       father[v]=u;
    }
    else
    {  rank[v]+=rank[u];
       father[u]=v;
    }
}
int main()
{   int u,v;
    while(scanf("%d%d",&u,&v))
    {  if(u==-1&&v==-1) break;
       CLR(indgree,0);
       Init();
       int num=0,count=0;//结点数,即顶点个个数 
        if(u==0&&v==0) printf("Case %d is a tree.\n",sum++);
       else 
       {  if(!sign[u]) {sign[u]=1;num++;}//若是没有用到标记用到,且点数+1 
          if(!sign[v]) {sign[v]=1;num++;} 
          indgree[v]++;//点v的入度+1 
          count++;//记录边数 
            Union(u,v);
          while(cin>>u>>v&&u||v)
          {   if(!sign[u]) {sign[u]=1;num++;}
              if(!sign[v]) {sign[v]=1;num++;} 
              indgree[v]++;
              count++;
              Union(u,v);
          }
          int add=0,flag=0;//add保存父结点个数,即判断树的根结点的个数 
            for(int i=0;i<MAX;i++)
             if(sign[i]&&father[i]==i) add++;
          if(add==1) flag=1;//检查是不是只有一个根结点,不是直接输出不是树 
            if(flag&&num-count==1)//满足只有一个根结点且满足结点数-边数=1
          {  for(int i=0;i<MAX;i++)
               if(sign[i]&&indgree[i]>1) flag=0;//满足除根结点以外的结点入读只能为1
             if(!flag) printf("Case %d is not a tree.\n",sum++);
             else  printf("Case %d is a tree.\n",sum++); 
          } 
          else printf("Case %d is not a tree.\n",sum++); 
       }
    }
    return 0;
}

要注意hdu 1325中的结束语句是当两个数都小于0~~不能写都等于-1,否则会TLE的~~
 nyist  208(supermarket)题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=208(贪心+并查集)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int MAX=10010;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
int father[MAX],rank[MAX],n;
class Supermarket{
public:
    Supermarket(){value=time=0;}
    Supermarket(int v,int t):value(v),time(t){}
    int Value() const {return value;}
    int Time() const {return time;}
    friend bool operator<(const Supermarket &s1,const Supermarket &s2)//得加friend  
    {   return s1.value>s2.value;
    }
private:
    int value;
    int time;      
};
class UnionFindSet{
public:
    void Init();   
    int Find(int u)
    {   return father[u]==-1?u:Find(father[u]); }
    void Union(int u,int v)
    {   u=Find(u);
        v=Find(v);
        father[v]=u;
    }
private:
    int father[MAX];
    int rank[MAX];
}; 
inline void UnionFindSet::Init()
{   CLR(father,-1);
    fill(rank,rank+MAX,1);
}
int main()
{   int value,time;
    while(scanf("%d",&n)!=EOF)
    {  int sum=0;
       vector<Supermarket> v;
       UnionFindSet U; 
       U.Init();
       for(int i=0;i<n;i++)
       {  scanf("%d%d",&value,&time);
          v.push_back(Supermarket(value,time));
       }
       sort(v.begin(),v.end());
       for(vector<Supermarket>::size_type i=0;i<v.size();i++)
       {  int u=U.Find(v[i].Time());
          if(u) 
          { U.Union(u-1,u);
            sum+=v[i].Value();
          } 
       }
       cout<<sum<<endl;
    }
    return 0;
}

得用scanf输入~~不然会超时~
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值