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;
}

你可能感兴趣的:(TOJ3660家庭关系(并查集+hash+图的连通性))