scau_大牛之路2(并查集)

原创 2015年11月20日 20:10:38

8618 大牛之路II

该题有题解

时间限制:500MS  内存限制:1000K
提交次数:138 通过次数:31

题型: 编程题   语言: G++;GCC

Description

要成为ACM大牛,要掌握很多必需的知识点。某些知识点可以推导出别的知识点,所以在比赛中遇到的新问题,
很多时候可以由你学过的知识中推导得到。现在给出要掌握的所有知识点数及知识点之间的推导关系。
注意,若A知识可以直接(间接)推导出B知识,B知识也是有可能直接(间接)推导出A知识的。
一个新手想尽快具有解决所有知识点的能力,他至少需要掌握多少知识呢?



输入格式

多组数据,每组数据格式为:
第一行1<=n<=18,0<=m<=n*n.。n表示必需掌握的知识点数目,编号0~n-1。m为知识点间推导关系总数。接下来m
行,每行A B两个数,表示从A知识可以推导出B知识。
当n==0 && m==0时,结束程序。两个Case间有一空行。


输出格式

一个数x,表示最少要掌握的知识数。


输入样例

8 4
0 1
0 2
1 3
1 4

2 2
0 1
1 0

0 0


输出样例

4
1

这道题用并查集思想能很高效解决,引用一下大神的代码
int pre[1000 ];
int find(int x)                                                                                        //查找根节点
{ 
    int r=x;
    while ( pre[r ] != r )                                                                  //返回根节点 r
          r=pre[r ];
 
    int i=x , j ;
    while( i != r )                                                                              //路径压缩
    {
         j = pre[ i ]; // 在改变上级之前用临时变量  j 记录下他的值 
         pre[ i ]= r ; //把上级改为根节点
         i=j;
    }
    return r ;
}
 
 
void join(int x,int y)                                                                      //判断x y是否连通,
                                              //如果已经连通,就不用管了 //如果不连通,就把它们所在的连通分支合并起,
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
        pre[fx ]=fy;
}


不过这道题得具体分析,比如路径压缩就不行了,这样会让知识的推导关系乱掉。同时推导方向是固定的,不是双向的,所以需要加上flag数组储存。
给出代码纪念
<pre name="code" class="cpp">#include <stdio.h>
#include <string.h>
int pre[20];
int flag[20];

int find(int x)
{
    int r=x;
    while(pre[r]!=r)
    {
        r=pre[r];
    }
   /* int i=x,j;
    while(i!=r)
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }*/
    return r;
}
int main()
{
    int n,m,i;
    while((scanf("%d %d",&n,&m)==2)&&(n||m))
    {
        memset(flag,0,sizeof(flag));
        int a,b,a1,b1,count=0;
        for(i=0;i<n;i++)
        {
            pre[i]=i;
        }
        while(m--)
        {
            scanf("%d %d",&a,&b);
            if(flag[b])
            continue;
            flag[b]=1;
            a1=find(a);
            b1=find(b);
            if(a1!=b1)
            {
                pre[b1]=a1;
            }
        }
        for(i=0;i<n;i++)
        {
            if(pre[i]==i)
            count++;
        }
        printf("%d\n",count);
    }
    return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

ACM复习(12)8618大牛之路II

Description 要成为ACM大牛,要掌握很多必需的知识点。某些知识点可以推导出别的知识点,所以在比赛中遇到的新问题,很多时候可以由你学过的知识中推导得到。现在给出要掌握的所有知识点数及知识点...
  • sinat_34200786
  • sinat_34200786
  • 2017年11月19日 19:19
  • 93

8611 大牛之路I

 8611 大牛之路I 时间限制:500MS  内存限制:1000K 提交次数:0 通过次数:0 题型: 编程题   语言: 无限制   Description 要成为ACM大牛...
  • xyh_Adolph
  • xyh_Adolph
  • 2014年06月06日 13:19
  • 848

新人程序员的大牛进阶之路

又到了一年毕业季,很多公司里面涌入大量的新人。这时候一般情况下项目负责人就会给新人看项目代码,让新人自己热身,这里我就给新人们12点建议,扶上战马,送你早日成为大牛 1.对代码花时间解构出来那一...
  • sanjing_shou
  • sanjing_shou
  • 2017年03月19日 17:39
  • 546

前端大牛的修炼之路从现在开始

加油!
  • YMJxiaojia
  • YMJxiaojia
  • 2014年10月20日 20:28
  • 136

ACM复习(9)8611 大牛之路I

Description 要成为ACM大牛,要掌握很多必需的知识点。某些知识点可以推导出别的知识点,所以在比赛中遇到的新问题,很多时候可以由你学过的知识中推导得到。现在给出要掌握的所有知识点数及知识点之...
  • sinat_34200786
  • sinat_34200786
  • 2017年11月04日 20:42
  • 129

JAVAEE 大牛成长之路

我也搞了几年JAVA了,由于一向懒惰,没有成为大牛,只是一普通程序猿,不爱玩社交网站,不爱玩微博,唯独喜欢百度贴吧,潜水很久了,手痒来给新人分享下从新手成长为老鸟的已见,也刷刷存在感,应该不比曝照差吧...
  • snioper007
  • snioper007
  • 2014年09月02日 16:18
  • 1553

我的python进阶之路一

4-1 比萨:想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for循环将每种比萨的名称打印出来。 (1)修改这个循环,使其打印包含比萨名称的句子,而不仅仅shi比萨的名称。对于...
  • L_dream_2016
  • L_dream_2016
  • 2017年04月26日 21:18
  • 410

Java技术大牛之路

打个比方吧,这位牛人23岁毕业,做了两年嵌入式C编程,25岁时,突然对Java的优雅设计情有独钟,而正好这时,公司有个Java项目,Java技术之旅开始了。 1、最开始三个月,开始接触Java,比如接...
  • zjh_1110120
  • zjh_1110120
  • 2016年05月21日 10:18
  • 3810

Python大牛编程习惯

python学习交流
  • python233
  • python233
  • 2017年04月18日 22:03
  • 494

求生之路2 游戏资料详细与细节

武器介绍 近身攻击:推开所有体积比较小的僵尸,或者拯救队友,是整个游戏最关键的动作近身武器(除电锯): 近身武器的伤害400,打WITCH时候变为250 斧头、吉他等武器攻击范围最远,砍刀、警棍...
  • qq_30274105
  • qq_30274105
  • 2016年12月05日 11:03
  • 555
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:scau_大牛之路2(并查集)
举报原因:
原因补充:

(最多只允许输入30个字)