TOJ3660家庭关系(并查集+hash+图的连通性)

家庭关系 分享至QQ空间 去爱问答提问或回答

时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte
总提交: 38            测试通过: 9

描述

 

给定若干家庭成员之间的关系,判断2个人是否属于同一家庭,即2个人之间均可以通过这些关系直接或者间接联系。

 

输入

 

输入数据有多组,每组数据的第一行为一个正整数n(1<=n<=100),表示有100个关系描述,接下来有n行,每行的描述方式为:
p1 p2 c
其中p1、p2和c均为一串文本,表示每个人的姓名,p1和p2为c的父亲和母亲。
最后一行包含2个字符串a和b,为待判断的两个人的姓名。
每个人的姓名由大小写字母组成,长度不超过80。

若n为0,表示输入结束。

 

输出

 

如果a和b在同一个家庭中,则输出Yes
否则输出No

 

样例输入

 

2

Barbara Bill Ted

Nancy Ted John

John Barbara

3

Lois Frank Jack

Florence Bill Fred

Annie Fred James

James Jack

0

 

样例输出

 

Yes

No

 

题目上传者

crq

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <vector>

#include <queue>

#include <map>

using namespace std;

const int maxn = 1000;

int gn;



int f[maxn];



int getfather(int x) {

    if(x == f[x]) return x;

    else return f[x] = getfather(f[x]);

}



void work(int x, int y, int z) {

    int t1 = getfather(x);

    int t2 = getfather(y);

    if(t1 != t2) {

        f[t1] = t2;

    }

    int t3 = getfather(z);

    if(t2 != t3) {

        f[t3] = t2;

    }

}



int main()

{

    int i, j;

    map<string, int> mymap;

    map<string, int>::iterator it;

    while(scanf("%d", &gn) != EOF && gn)

    {

        int cnt = 0;

        for(i = 0; i < maxn; i++) f[i] = i;//!!!!

        mymap.clear();

        string str[3];

        for(i = 0; i < 3; i++) str[i].clear();

        for(i = 0; i < gn; i++) {

            for(j = 0; j < 3; j++) {

                cin >> str[j];

                it = mymap.find(str[j]);

                if(it == mymap.end()){

                    mymap[str[j]] = ++cnt;

                }

            }

            int a[3];

            a[0] = mymap[str[0]];

            a[1] = mymap[str[1]];

            a[2] = mymap[str[2]];

            work(a[0], a[1], a[2]);

        }

        string s, t;

        cin >> s >> t;//所有判读的人不在集合里面.

        int start = 0;

        int endx = 0;

        start = mymap[s];

       // printf("start = %d\n", start);

        endx = mymap[t];

       // printf("endx = %d\n", endx);

        if(start == 0 || endx == 0) {//WA了好多次.

            printf("No\n");

            continue;

        }

        int t1 = getfather(start);

        int t2 = getfather(endx);

        if(t1 == t2)

            cout << "Yes" << endl;

        else cout << "No" << endl;

    }

    return 0;

}

你可能感兴趣的:(hash)