Problem A Succession

Problem A Succession

NCPC 2010 Problem A: Succession 1
Problem A
Succession
The king in Utopia has died without an heir. Now several nobles in the country claim the throne. The country law states that if the ruler has no heir, the person who is most related to the founder of the country should rule.
To determine who is most related we measure the amount of blood in the veins of a claimant that comes from the founder. A person gets half the blood from the father and the other half from the mother. A child to the founder would have 1/2 royal blood, that child’s child with another parent who is not of royal lineage would have 1/4 royal blood, and so on. The person with most blood from the founder is the one most related.
Input specifications
The first line contains two integers, N (2 ≤ N ≤ 50) and M (2 ≤ M ≤ 50). The second line contains the name of the founder of Utopia. Then follows N lines describing a family relation. Each such line contains three names, separated with a single space. The first name is a child and the remaining two names are the parents of the child. Then follows M lines containing the names of those who claims the throne. All names in the input will be between 1 and 10 characters long and only contain the lowercase English letters ’a’-’z’. The founder will not appear among the claimants, nor be described as a child to someone else.
Output specifications
A single line containing the name of the claimant with most blood from the founder. The input will be constructed so that the answer is unique. The family relations may not be realistic when considering sex, age etc. However, every child will have two unique parents and no one will be a descendent from themselves. No one will be listed as a child twice.
2 NCPC 2010 Problem A: Succession
Sample input 1 Sample output 1
9 2 edwardi charlesi edwardi diana philip charlesi mistress wilhelm mary philip matthew wilhelm helen edwardii charlesi laura alice laura charlesi helen alice bernard henrii edwardii roxane charlesii elizabeth henrii charlesii matthew
matthew
Sample input 2 Sample output 2
4 5 andrew betsy andrew flora carol andrew betsy dora andrew carol elena andrew dora carol dora elena flora gloria

继承
在乌托邦里的国王死了,没有继承人。现在,该国的几位贵族继承了王位。国家法律规定,如果统治者没有继承人,最与国家创始人有关的人应该统治。
为了确定谁是最相关的,我们测量了从创始人那里获得的血液的数量。一个人从父亲那里得到一半的血液,另一半来自母亲。一个孩子的创始人会有1 / 2的皇室血统,那个孩子的孩子和另一个没有皇室血统的父母会有1 / 4的皇家血统,等等。从创始人身上获得最多血液的人是最相关的。
输入规格
第一行包含两个整数N(2≤N≤50)和M(2 M≤≤50)。第二行是乌托邦的创始人的名字。接着是描述家庭关系的N行。每一行都包含三个名称,分别与一个空格隔开。第一个名字是一个孩子,剩下的两个名字是孩子的父母。然后是M行,其中包含那些声称王座的人的名字。输入的所有名称长度在1到10个字符之间,只包含小写的英文字母“a”-“z”。创始人不会出现在索赔人当中,也不会被描述为其他人的孩子。
输出规格
一种单行,包含创始人的大部分血液的索赔人的姓名。输入将会被构造,以使答案是唯一的。家庭关系在考虑性别、年龄等方面可能不现实,但每个孩子都有两个独特的父母,没有人会是他们自己的后代。没有人会被列为孩子两次。

SPFA的变式。每次将增广路上改变的结点入队。注意数组范围即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 200;

int tot = 1;    //已有的皇室的数量 
int inq[MAXN];

struct People{
    char name[11];
    vector<int> son;
    double bld[2];//0:father    1:mather
    int fa;         //father    
    int ma;         //mather

    People() {
        memset(name, 0, sizeof name);
        bld[0] = bld[1] = 0;
        fa = ma = 0;
    }
}p[MAXN];

bool same(char *s1, char *s2) {
    if (strlen(s1) != strlen(s2)) return 0;
    for (int i = 0; s1[i]; ++i)
      if (s1[i] != s2[i])
        return 0;
    return 1;
}

int find(char *s) {
    for (int i = 1; i <= tot; ++i)
      if (same(s, p[i].name))
        return i;
    ++tot;
    for (int i = 0; s[i]; ++i)
      p[tot].name[i] = s[i];
    return tot;
}

void bfs() {
    queue<int> Q;
    Q.push(1);
    while (!Q.empty()) {
      int x = Q.front();
      Q.pop();
      inq[x] = 0;
      double now = (p[x].bld[0] + p[x].bld[1]) / 2;
      for (int i = 0; i < p[x].son.size(); ++i) {
        int y = p[x].son[i];
        int rel = x == p[y].fa ? 0 : 1; //relation_ship
        double past = p[y].bld[rel];
        p[y].bld[rel] = now;
        if (past != p[y].bld[rel] && !inq[y]) inq[y] = 1, Q.push(y);
      }
    }
}

char s[11], s1[11], s2[11], s3[11];

int main()
{
    freopen("in.txt", "r", stdin);
    int n, m;
    scanf("%d%d", &n, &m);
    scanf("%s", p[1].name);
    p[1].bld[0] = 536870912 / 2;
    for (int i = 1; i <= n; ++i) {
      scanf("%s%s%s", s1, s2, s3);
      int id1 = find(s1), id2 = find(s2), id3 = find(s3);
      p[id1].fa = id2;
      p[id1].ma = id3;
      p[id2].son.push_back(id1);
      p[id3].son.push_back(id1);
    }
    bfs();
    double maxBld = 0;
    int id;
    for (int j = 1; j <= m; ++j) {
      scanf("%s", s);
      for (int i = 2; i <= tot; ++i) 
        if (same(s, p[i].name)) {
          if (p[i].bld[0] + p[i].bld[1] > maxBld) {
            maxBld = p[i].bld[0] + p[i].bld[1];
            id = i;
          }
          break;
        } 
    }
    printf("%s", p[id].name);
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值