1. 程式人生 > >哈理工oj 1073 病毒

哈理工oj 1073 病毒

Description

某種病毒襲擊了某地區,該地區有N(1≤N≤50000)人,分別編號為0,1,...,N-1,現在0號已被確診,所有0的直接朋友和間接朋友都要被隔離。例如:0與1是直接朋友,1與2是直接朋友,則0、2就是間接朋友,那麼0、1、2都須被隔離。現在,已查明有M(1≤M≤10000)個直接朋友關係。如:0,2就表示0,2是直接朋友關係。
請你程式設計計算,有多少人要被隔離。

Input

第一行包含兩個正整數N(1≤N≤50000),M(1≤M≤100000),分別表示人數和接觸關係數量;
在接下來的M行中,每行表示一次接觸,;
每行包括兩個整數U, V(0 <= U, V < N)表示一個直接朋友關係。

Output

輸出資料僅包含一個整數,為共需隔離的人數(包含0號在內)。

Sample Input

100 4
0 1
1 2
3 4
4 5

Sample Output

3

由於0號已經確診感染病毒,那麼只需找出0號的直接朋友與間接朋友即可。

程式碼如下:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int n,m;
int i;
int fa[50005];
void inin(int n)    //初始化 使每個成員的父親都是他自己
{
    for(i=0; i<n; i++)
    {
        fa[i]=i;
    }
    return ;
}
int getf(int n)   //利用遞迴 找到n的父親
{
    if(fa[n]==n)  //如果n的父親是他自己 那麼返回n;
    {
        return n;
    }
    else                 //如果不是 進行遞迴操作
    {
        fa[n]=getf(fa[n]);  
        return fa[n];
    }
}
void hr(int v,int j)   
{
    int fv,fj;   //fv為v的父親,fj為j的父親
    fv=getf(v);
    fj=getf(j);
    if(fv<fj)    //如果fv<fj  那麼把fv作為fj的父親
    {
        fa[fj]=fv;
    }
    else if(fv>fj)  //如果fv>fj  那麼把fj作為fv的父親
    {
        fa[fv]=fj;
    }
    return;
}
int main()
{
    int x,y;
    while(cin>>n>>m)
    {
        memset(fa,0,sizeof(fa));
        inin(n);     //呼叫函式對陣列 fa 進行初始化
        int ans=0;
        for(i=1; i<=m; i++)
        {
            cin>>x>>y;
            hr(x,y);
        }
        for(i=0; i<n; i++) //遍歷0-n 如果i的父親等於0的父親 那麼 ans++
        {
            if(getf(i)==fa[0])
            {
                ans++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}