10317 Fans of Footbal Teams
时间限制:1000MS 内存限制:65535K
题型: 编程题 语言: 无限制
Description
Two famous football teams, named AC Milan(AC米兰) and Inter Milan(国际米兰) will have a match in GuangZhou City, which is
exciting. So a lot of fans get together to watch the wonderful match. This trouble the local polices. In order to avoid a
chaos caused by fans of the two teams, the police office in GuangZhou City decides to arrange the seats of the gymnasium(体育馆)
during the match. All fans of AC Milan seat Noth, while all fans of Inter Milan seat South . However, the police first needs
to identify which team a fan support. The present question is, given two fans; do they support a same team? You must give
your judgment based on incomplete information. Assume N (N <= 10^5) fans are currently in GuangZhou City, numbered from 1 to N. You will be given M (M <= 10^5) messages
in sequence, which are in the following two kinds: 1. D [a] [b]
where [a] and [b] are the numbers of two fans, and they support different teams. 2. A [a] [b]
where [a] and [b] are the numbers of two fans. This requires you to decide whether a and b support a same team.
输入格式
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow.
Each test case begins with a line with two integers N and M, followed by M lines each containing one message as described above.
输出格式
For each message "A [a] [b]" in each case, your program should give the judgment based on the information got before.
The answers might be one of "Support the same team.", "Support different teams." and "Not sure yet."
输入样例
1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
输出样例
Not sure yet.
Support different teams.
Support the same team.
作者
admin
解题思路
【题意】AC米兰和国际米兰要在广州比赛从而吸引众多的球迷前来观看,为了保证治安问题保安要为球迷分配观看的位置,现在需要知道哪些球迷支持相同的球队,哪些球迷支持不同的球迷,现在根据给的数据n(球迷的数量,编号从1到n),m(条信息,说明这两个球迷支持相反的球队或需要你输出判断这两个球迷支持球队的信息)
【随笔】开始认为只有两种情况,要么支持相同的球队,要么支持相反的球队,打算用一个数组就解决问题,后来发现这样下去有问题,比如出现两组支持不同球队的四个人,然后接下来的某条信息将其中的两个人联系起来,那么从中还可以得到四个人的信息,手写出数据来试着分析很容易发现其中的规律
D 1 2; D 2 4; D 3 5; D 7 8; D 5 2; D 1 7; D 6 9; D 6 10;
【解题】~并查集~给你的D中的数据主要分三种情况,两个球迷之前均没表明立场的;其一表明立场的;两者均有表明立场的;用一个数组构造并查集,用另一数组存储各自的死对头,死对头每次我都及时更新,其实后来想想是没必要的,因为敌人的敌人就是朋友,在构成的并查集里最终还是能找到源点表明不同的立场。存储死对头主要是想判断是否是”无法判断“这种情况。而存储死对头的还有一个作用是找到死对头的源点,将此时新增的死对头加入此行列。并查集查找源点的时候即使压缩路径,所以尽管每次都去查找,但是消耗的时间还不是很多。
【PS】这题恶心了好长的一段时间,主要是思路还不是很清晰,现在回想很多想法和考虑到的东西以及实现的方法还是没必要的,这里已经浪费了大半的时间
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define MAXN 100010 using namespace std; int middle[MAXN], digit[MAXN];
char same[] = "Support the same team.";
char dif[] = "Support different teams.";
char mix[] = "Not sure yet."; int find_father(int fac)
{//查找源头并及时压缩路径
return middle[fac] = fac == middle[fac] ? fac : find_father(middle[fac]);
} /*
void Print(int n)
{
static int cnt = 0;
for(int i=1; i<=n; i++)
{
printf("middle[%d] = %d, D[%d] = %d\n", i, middle[i], i, digit[i]);
}
printf("-------------------%d----------------------\n", ++cnt);
}
*/ int main()
{
#ifndef ONLINE_JUDGE
freopen("F:\\test\\input.txt", "r", stdin);
#endif // ONLINE_JUDGE int T;
int n, m, first, second, sum;
int father, foster, fir_father, sec_father, fir_foster, sec_foster;
char kind;
bool falg = false;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(int i=; i<=n; ++i)
{
middle[i] = i;
digit[i] = ;
}
for(int i=; i<m; ++i)
{
getchar();
scanf("%c", &kind);
scanf("%d%d", &first, &second);
if(kind == 'A')
{
fir_father = find_father(first);
sec_father = find_father(second);
if(fir_father == sec_father)
printf("%s\n", same);
else
{
fir_foster = find_father(digit[fir_father]);
if(fir_foster == sec_father)
printf("%s\n", dif);
else
printf("%s\n", mix);
} }
else if(kind == 'D')
{
if(!digit[first] && !digit[second])
{//互相存储死对头的编号
digit[first] = second;
digit[second] = first;
}
else if(!digit[first] && digit[second])
{
father = find_father(second);
foster = find_father(digit[father]);
middle[foster] = first;
digit[first] = father;
}
else if(digit[first] && !digit[second])
{
father = find_father(first);
foster = find_father(digit[father]);
middle[foster] = second;
digit[second] = father;
}
else
{
fir_father = find_father(first);
sec_father = find_father(second);
fir_foster = find_father(digit[fir_father]);
sec_foster = find_father(digit[sec_father]);
middle[fir_foster] = sec_father;
middle[sec_foster] = fir_father;
}
}
}
} return ;
}