poj 1611

1611:The Suspects

 

总时间限制: 
1000ms
 
内存限制: 
65536kB
描述
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others. In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP). Once a member in a group is a suspect, all members in the group are suspects. However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.
输入
The input file contains several cases. Each test case begins with two integers n and m in a line, where n is the number of students, and m is the number of groups. You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered by a unique integer between 0 and n−1, and initially student 0 is recognized as a suspect in all the cases. This line is followed by m member lists of the groups, one line per group. Each line begins with an integer k by itself representing the number of members in the group. Following the number of members, there are k integers representing the students in this group. All the integers in a line are separated by at least one space. A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
输出
For each case, output the number of suspects in one line.

样例输入

100 4
2 1 2
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
样例输出
4
1
1

很普通的一道题,就按照模板套就能AC,奈何自己非得作死,想搞点新花样,结果wa到自闭。。。

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=100000;
int p[N];
int b[N]; 
int find(int x)     //首先传入一个值x 
{
    int k, j, r;
    r = x;                    
    while(r != p[r])     //查找跟节点
        r = p[r];      //找到跟节点,用r记录下
    k = x;                 //k记录最初x,最初的子节点 
    while(k != r)             //如果此时子节点不等于x的根节点,即k不是皇帝 
    {
        j = p[k];         //用j暂存x的原来的父节点
        p[k] = r;        //原来的父节点指向跟节点
        k = j;                    //k移到父节点,作为子节点参与下一次循环,直到k为皇帝 
    }                      //结束循环,x以上的所有人都作为一级,指向根节点; 
    return r;         //返回根节点的值            
}
void join(int x,int y)
{
    int dx=find(x);   //找到x的老大 
    int dy=find(y);   //找到y的老大 
    if(dx!=dy)
    p[dx]=dy;
    return;
}
int main()
{
    int n,m;
    ios::sync_with_stdio(false);
    while(cin>>n>>m&&n||m)          //m行 
    {
        for(int i=0;i<n;i++)        //从0到n-1个同学,初始化 
            p[i]=i;
        for(int k=0;k<m;k++){      //m行 
            int num,a;          //每行num个数 
            cin>>num;
            cin>>b[0];        //插旗,以第一个数为队长 */
            for(int i=1;i<num;i++)
            {              //路径亚索 
                cin>>b[i];    
                join(b[i],b[i-1]);   
            }
        }                          //m行输入完毕
        int ans=0;
        for(int i=0;i<n;i++) {
            if(find(i)==find(0))
                ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}


1、可能是评测机不同,ios::sync_with_stdio(false);在vjudge上基本没用,还是老老实实用scanf,printf吧;

2、路径压缩算法确实能减少大量时间,不过要是过于简单或数据量很小,用不用都无所谓。

3、在写代码时候一定要调输入法!!!一定要换成中文(简体)-美式键盘!!!一定要换成中文(简体)-美式键盘!!!一定要换成中文(简体)-美式键盘!!!虽然不是这道题,而是一道更简单的题带给我的血的教训!!!wa到自闭啊啊啊啊!!!

以上。




posted @ 2019-08-05 20:36  Luoha  阅读(153)  评论(0编辑  收藏  举报