关系

Problem description
  在多年以后,seat26对多年前的事情已经记得不太清楚了,每次看见人,他都觉得这个人与他有关系,我们知道二个人的关系有以下几种: 
1)他们是同一个班级的。

 

2)他们是同一个专业的。

3)他们是同一个学校的。

4)他们不满足以上三种关系。 
我们知道,当二个人是同一个班级的,那么他们也一定是同一个专业的。当二人是同一个专业的,那么他们一定是同一个学校的。而且当A,B是同一班级的,B,C是同一个班级的,那么A,C也是一定是同一个班级的。当然对于同一个专业的,同一个学校的这种传递性也是满足的。 
现在seat26通过各种方式知道了一群人的一些关系,但是他想知道这群人之间其他的关系。 

Input
  输入有多组数据,每组数据第一行有二个正整数N,M,C(2<=N<=100000,1<=M<=100000,1<=C<=10000)N表示N个人,M表示这N个人的M条关系,接下来有M行,每行有三个整数Pi,Qi,Ti,(1<=Pi,Qi<=N,1<=Ti<=4)表示知道Pi和Qi的关系为Ti,当Ti=1时,表示他们是同一个班级的,Ti=2时表示他们是同一个专业的,Ti=3时表示他们是同一个学校的,Ti=4表示不知道他们具体的关系,即他们可能是一个班级,一个专业或一个学校的,也有可能都不满足。 
接下来是C行代表C个询问,每行二个正整数Pi,Qi(1<=Pi,Qi<=N)表示询问Pi和Qi的关系 
最后一行是0,0,0,表示输入结束且不需要处理。 

Output
  对于每组数据输出C+1行,第一行输出 Case d:  代表第d组数据 
接下来C行,每行包括一个正整数Ti,表示第i个询问Pi和Qi的关系,Ti表示关系类型与输入相同。 

Sample Input
4 2 2
1 2 1
2 3 2
3 1
1 4

4 3 2 
1 2 3
4 3 1
1 4 2
2 3
1 3

4 2 2
1 2 4
1 2 3
1 2
3 4
0 0 0
Sample Output
Case 1:
2
4
Case 2:
3
2
Case 3:
3
4
Problem Source
  湖南师范大学第四届大学生计算机程序设计竞赛
#include<stdio.h>

int p1[100005];
int p2[100005];
int p3[100005];
int n,m,x;

void init()
{
    int i;
    for(i=1; i<=n; i++)
    {
        p1[i]=i;
        p2[i]=i;
        p3[i]=i;
    }
}
int find1(int x)
{
    if(p1[x]==x) return x;
    else p1[x]=find1(p1[x]);
}
int find2(int x)
{
    if(p2[x]==x) return x;
    else p2[x]=find2(p2[x]);
}
int find3(int x)
{
    if(p3[x]==x) return x;
    else p3[x]=find3(p3[x]);
}
void union1(int a,int b)
{
    int s=find1(a);
    int t=find1(b);
    if(s==t) return;
    p1[s]=t;
}
void union2(int a,int b)
{
    int s=find2(a);
    int t=find2(b);
    if(s==t) return;
    p2[s]=t;
}
void union3(int a,int b)
{
    int s=find3(a);
    int t=find3(b);
    if(s==t) return;
    p3[s]=t;
}
int main()
{
    int i,j,a,b,c,p,q,ca=0,x;
    while(scanf("%d %d %d",&n,&m,&x)&&(n||m||x))
    {
        ca++;
        init();
        for(i=1; i<=m; i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            if(c==1)
            {
                union1(a,b);
                union2(a,b);
                union3(a,b);
            }
            else if(c==2)
            {
                union2(a,b);
                union3(a,b);
            }
            else if(c==3) union3(a,b);
        }
        printf("Case %d:\n",ca);
        for(i=1; i<=x; i++)
        {
            scanf("%d %d",&p,&q);
            if(find1(p)==find1(q)) puts("1");
            else if(find2(p)==find2(q)) puts("2");
            else if(find3(p)==find3(q)) puts("3");
            else puts("4");
        }
    }
    return 0;
}
并查集

 

posted @ 2013-09-07 21:44  1002liu  阅读(190)  评论(0编辑  收藏  举报