2016HUAS_ACM暑假集训2B - The Suspects(感染者)

并查集初步应用,还不是很熟练。并查集两个主要函数:Union和Find。Union通常把两条不连通的支路使其连通;Find用来查找根节点,必要的要进行路径压缩。

大致题意:0号学生是默认的感染者,在M组团体中,如果出现了0号,则整个团体都是感染者。

样例:

Sample Input

100 4                        //第一行两个整数N,M,表示N个学生(已编号0~N-1),M个团体  (0 < N <= 30000,0 <= M <= 500)

2 1 2                        //以下M行,第一个数是该团体的人数K  后面是K个学生的编号

5 10 13 11 12 14

2 0 1

2 99 2

200 2

1 5

5 1 2 3 4 5

1 0

0 0

Sanple Output(输出每组案例的感染者数目)

4

1

1

 1 #include<iostream>
 2 using namespace std;
 3
 4 int node[30001],flag[30001];
 5 int n,m,num;
 6
 7 void Init(int n)//初始化
 8 {
 9     for(int i=0;i<n;i++)
10         node[i]=i;
11 }
12
13 int find(int x)//查找x的父节点
14 {
15     if(node[x]==x)//父节点是它本身
16         return x;
17     else//往上找
18         return     node[x]=find(node[x]);
19 }
20
21
22 void mix(int x,int y)//使x和y连通
23 {
24     x=find(x);
25     y=find(y);
26     node[x]=y;
27 }
28
29 int main()
30 {
31     int i;
32     while((cin>>n>>m)&&n*n+m*m)
33     {
34         Init(n);
35         while(m--)
36         {
37             cin>>num;
38             for(i=0;i<num;i++)
39                 cin>>flag[i];
40             for(i=1;i<num;i++)
41                 mix(flag[i-1],flag[i]);//把输入的各点连通
42         }
43         int c=0;
44         for(i=0;i<n;i++)
45         {
46             if(find(i)==find(0))//判断父节点是否与一号感染者相同
47                 c++;
48         }
49         cout<<c<<endl;
50     }
51     return 0;
52 }

时间: 2024-10-10 21:36:42

2016HUAS_ACM暑假集训2B - The Suspects(感染者)的相关文章

2016HUAS_ACM暑假集训2L - Points on Cycle(圆上的点)

一个简单的几何题,自己在纸上列出方程解出结果的表达式,再用程序表达出来就行了. 大致题意:一个圆心在原点的圆,半径未知,现在给你圆上的一点,让你在这个圆上找到另外两点,使得这三点构成的三角形的周长最长. 样例输入:(第一行为一个整数N,表示后面有N组案例,每个案例给出一组圆上点的坐标) 2 1.500        2.000 563.585    1.251 样例输出:(其他两个点的坐标) 0.982 -2.299 -2.482 0.299 -280.709  -488.704  -282.8

2016HUAS_ACM暑假集训4F - 数论

这个题目,如果没找到方向,确实有点一头雾水.但是如果你找对方向了,AC是分分钟的事.答案就是看n和m是否有除1之外的公约数. 简单证明:设n和m最大公约数不是1,假设为p.n和m总可以化为一个数乘以k的形式吧,不妨令n=a*k,m=b*k(暂时不知道有什么用); 那么狼第一次遍历的洞口编号为0,m,2m......(假设这些洞的编号都在n-1以内),假设狼第i次进洞会超过n-1,则此时本应该是i*m,但是i*m>n-1,所以这次洞口的编号是(i*m)%n,但是,但是,但是(i*m)%n=i*b*

2016HUAS_ACM暑假集训1A - 士兵队列训练问题

这道题我觉得是个简单的模拟题,整理一下思路,弄清楚题意就好了. 新手上路,采用两个数组进行交互赋值,用的方法也比较笨,思路差不多都在代码的注释里了. 下面是题目大意: 首先将士兵从1开始编号(士兵总数不超过5000),然后开始1 2 1 2...报数,报到2的士兵出列,剩下的向小序号方向靠拢,然后按照1 2 3 1 2 3... 报数,报到3的出列.以此类推(1 2 1 2...报数后再1 2 3 1 2 3...报数),直到剩下的士兵人数不超过3人,并且输出他们原来的编号. 格式要求如下: 第

2016HUAS_ACM暑假集训3G - 还是畅通工程

最小生成树,题目简单.套的Prim模板,其他的题目比较有意义. Sample Input 3                             //村庄个数1 2 1                       //连通情况及权值1 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50 Sample Output       //输出最小生成树的权 3 5 1 #include<stdio.h> 2 #include<string.h> 3 #de

2016HUAS_ACM暑假集训4A - 递推

利用组合公式C(n,m)=C(n-1,m)+C(n-1,m-1).也就是从n个数里面选择m个数.按递增方式放在每一层循环. 杨辉三角+二项式定理,还真是挺有“意思”的一道题.说实话,非原创.见谅..... 题目大意:一个循环结构有m层,第一层是1~n,以后每加一层,循环变量的初值都都在上一层的基础上加1. 例如:第一层是1~n,那么第二层就是2~n,以此类推.求出m层的循环次数(答案对1007取模). Sample Input 2                                

2016HUAS_ACM暑假集训4C - 递推

题目大意:给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形. 这里我们可以这样看: 对于行:假如是m单位长度,则长度为1的矩形有m个,长度为2的矩形有m-1个......长度为m的只有1个,所以总共的矩形是1+2+...+m=(1+m)*m/2个 对于列:同行可以. 所以,总的矩形数=行*列.得出通项公式N(m,n) =  (1+m)*(1+n)*m*n/4. #include<iostream> using namespace std; int t,n,m; int main(

2016HUAS_ACM暑假集训4D - 计数,排列

一个错排公式的基础应用. 大致题意:求n个数的错误排列方式.(每个都要错) 在这里先贴一下错排公式:D(1)=0:D(2)=1:D(n)=(n-1)*(D(n-1)+D(n-2)) 它的推导也非常有意思,用的应该是递归的思想吧(个人猜测). Sample Input 2 3 Sample Output 1 2 这题注意两点: 1.长整型__int64或者long long 2.最好打一下表,防止超时 然后,然后就过了呗...... #include<iostream> #include<

2016HUAS_ACM暑假集训2E - I Hate It

又是一个线段树的应用,不过跟上一题(D-排兵布阵)不同的是,这次是求某段区间上的最值,而不是某段区间和.当然,数据更新是必须的.D题注释已经很详细了,所以这题注释少点. 大致题意:给你N个已经排好的学生成绩,然后有M条指令,输出对应指令的结果.指令有两种: 1.Q  i  j:询问i到j的最值 2.U  i  j:把学生编号为i的成绩改为j 输入输出格式: Sample Input 5     6                    //第一行两个整数N,M,表示N个学生和M条指令( 0<N<

2016HUAS_ACM暑假集训4K - 基础DP

我不知道怎么用DP,不过DFS挺好用.DFS思路很明显,搜索.记录,如果刚好找到总价值的一半就说明搜索成功. 题目大意:每组6个数,分别表示价值1到6的物品个数.现在问你能不能根据价值均分. Sample Input                                  //6种价值物品的个数,全为0时结束 1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0 Sample Output                              //注意格式,空两行