关系 |
Time Limit: 3000ms, Special Time Limit:7500ms, Memory Limit:65536KB |
Total submit users: 34, Accepted users: 29 |
Problem 11312 : No special judgement |
Problem description |
在多年以后,seat26对多年前的事情已经记得不太清楚了,每次看见人,他都觉得这个人与他有关系,我们知道二个人的关系有以下几种: 1)他们是同一个班级的。 2)他们是同一个专业的。 3)他们是同一个学校的。 4)他们不满足以上三种关系。 |
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 <iostream>
#include <cstring>
using namespace std;
#define maxn 100000+10
int p1[maxn],p2[maxn],p3[maxn];
int N,M,C;
void make_set1(int x){
for(int i=1;i<=x;i++)
p1[i] = i;
}
int find_set1(int x)
{
if(x != p1[x]){
p1[x] = find_set1(p1[x]); //寻找根节点的同时,更新节点的父节点
}
return p1[x];
}
void union_set1(int x,int y)
{
int a = find_set1(x);
int b = find_set1(y);
if(a == b)
return;
else
p1[a] = b;
}
void make_set2(int x){
for(int i=1;i<=x;i++)
p2[i] = i;
}
int find_set2(int x)
{
if(x != p2[x]){
p2[x] = find_set2(p2[x]); //寻找根节点的同时,更新节点的父节点
}
return p2[x];
}
void union_set2(int x,int y)
{
int a = find_set2(x);
int b = find_set2(y);
if(a == b)
return;
else
p2[a] = b;
}
void make_set3(int x){
for(int i=1;i<=x;i++)
p3[i] = i;
}
int find_set3(int x)
{
if(x != p3[x]){
p3[x] = find_set3(p3[x]); //寻找根节点的同时,更新节点的父节点
}
return p3[x];
}
void union_set3(int x,int y)
{
int a = find_set3(x);
int b = find_set3(y);
if(a == b)
return;
else
p3[a] = b;
}
int main()
{
int count = 1;
while(cin>>N>>M>>C && (N || M || C)){
make_set1(N);
make_set2(N);
make_set3(N);
for(int i=1;i<=M;i++){
int a,b,type;
scanf("%d %d %d",&a,&b,&type);
if(type == 1){
union_set1(a,b);
union_set2(a,b);
union_set3(a,b);
}
else if(type == 2){
union_set2(a,b);
union_set3(a,b);
}
else if(type == 3)
union_set3(a,b);
}
cout<<"Case "<<count<<":"<<endl;
count++;
for(int i=1;i<=C;i++){ //输出最近的一层关系
int a,b;
scanf("%d %d",&a,&b);
if(find_set1(a) == find_set1(b))
cout<<1<<endl;
else if(find_set2(a) == find_set2(b))
cout<<2<<endl;
else if(find_set3(a) == find_set3(b))
cout<<3<<endl;
else
cout<<4<<endl;
}
}
return 0;
}