社交網路 (並查集的應用)

PKU_CXK發表於2016-12-08
很簡單的並查集基礎應用,相當於連通圖的問題,將可連線的節點歸併到同一個節點下即可.直接上程式碼.

描述
隨著社交平臺的興起,人們之間的溝通變得越來越密切。通過Facebook的分享功能,只要你是對方的好友,你就可以轉發對方的狀態,並且你的名字將出現在“轉發鏈”上。經過若干次轉發以後,很可能A分享了一條好友C的狀態,而C的這條狀態實際上是分享B的,但A與B可能並不是好友,即A通過C間接分享了B的狀態。
給定你N個人之間的好友關係,好友關係一定是雙向的。只要兩個人是好友,他們就可以互相轉發對方的狀態,無論這條狀態是他自己的,還是他轉發了其他人的。現在請你統計,對於每兩個人,他們是否有可能間接轉發對方的狀態。

輸入

第一行1個整數N(1<=N<=300)。
接下來N行每行N個整數,表示一個N*N的01矩陣,若矩陣的第i行第j列是1,表示這兩個人是好友,0則表示不是好友。
保證矩陣的主對角線上都是1,並且矩陣關於主對角線對稱。

輸出

一個N*N的01矩陣,若矩陣的第i行第j列是1,表示這兩個人可能間接轉發對方的狀態,0則表示不可能。

#include <iostream>
#include <stdio.h>
using namespace std;

char str[310][310];
int n, b[310][310], father[310];

int find(int x)//返回祖先節點
{
    if(x == father[x])
        return father[x];
    father[x] = find(father[x]);
    return father[x];
}

void Union(int x,int y)
{
    int fx = find(x);
    int fy = find(y);
    if(fx != fy)
    {
        father[fx] = fy;
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        father[i] = i;
    for(int i=1;i<=n;i++)
    {
        cin>>str[i];
        for(int j=1;j<=n;j++)
        {
            if(str[i][j-1] == '1')
                Union(i,j);//歸併
        }
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            if(find(i) == find(j))
                b[i][j] = 1;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            printf("%d",b[i][j]);
        }
        printf("\n");
    }
    return 0;
}

相關文章