势力较量 | ||||||
| ||||||
Description | ||||||
在战火纷乱的古代有许多小国家。在这些小国家中,就会有一些强大的,一些弱小的。势力大的就会吞并势力小的, 形成更大的势力国家。现在给出你一些目前的国家势力关系,你能预算出以后的局势吗? 为了简化问题,给每个国家编号,像“国家1”, “国家2”......“国家N” 国家的较量首先从人数上进行比较,人数多的能打赢人数少的。如果两个国家的人数相同,就根据国家头目的编号来判断, 我们假设编号大的国家能打得过编号小的国家。 当两个国家相遇的时候,就会有一场打斗,且一定要分出胜负,输的就会归顺于赢得, 形成一个新的国家。 | ||||||
Input | ||||||
多组测试数据,处理到文件结束。对于每组数据: 第一行两个整数N,M。N为国家个数,M为关系数目。 接下来M行,每行两个整数u, v。表示国家u,国家v相遇,有一场打斗。 然后试一个整数Q,表示Q个询问。 接下来Q行,每行一个整数S。 (N<100, M < 100, Q < 100) | ||||||
Output | ||||||
Case k: 对于每个询问,输出两个整数, 第一个整数表示S所在国家的头目,第二个整数表示S所在国家里边一共有多少个小国家。 | ||||||
Sample Input | ||||||
5 3 1 2 1 3 4 5 2 1 5 5 4 1 2 1 3 1 4 1 5 4 2 3 4 5 | ||||||
Sample Output | ||||||
Case 1: 2 3 5 2 Case 2: 2 5 2 5 2 5 2 5 |
#include<bits/stdc++.h>
using namespace std;
struct node
{
int num, boss;
} pre[500];
int findx(int x)
{
return x == pre[x].boss ? x : pre[x].boss = findx(pre[x].boss);
}
int main()
{
int CASE = 0, n, m, q;
while(cin >> n >> m)
{
for(int i = 0; i <= n; i++)
{
pre[i].num = 1;
pre[i].boss = i;
}
for(int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
int x = findx(a);
int y = findx(b);
if(x == y)
continue;
else if(pre[x].num > pre[y].num)
{
pre[x].num += pre[y].num;
pre[y].boss = x;
}
else if(pre[x].num < pre[y].num)
{
pre[y].num += pre[x].num;
pre[x].boss = y;
}
else if(pre[x].num == pre[y].num)
{
if(pre[x].boss > pre[y].boss)
{
pre[x].num += pre[y].num;
pre[y].boss = x;
}
if(pre[x].boss < pre[y].boss)
{
pre[y].num += pre[x].num;
pre[x].boss = y;
}
}
}
printf("Case %d:\n", ++CASE);
cin >> q;
for(int i = 0; i < q; i++)
{
int ask;
cin >> ask;
int aa = findx(ask);
printf("%d %d\n", findx(ask), pre[aa].num);
}
}
return 0;
}