POJ:2139-Six Degrees of Cowvin Bacon

传送门:http://poj.org/problem?id=2139

Six Degrees of Cowvin Bacon

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 6709 Accepted: 3122

Description

The cows have been making movies lately, so they are ready to play a variant of the famous game “Six Degrees of Kevin Bacon”.

The game works like this: each cow is considered to be zero degrees of separation (degrees) away from herself. If two distinct cows have been in a movie together, each is considered to be one ‘degree’ away from the other. If a two cows have never worked together but have both worked with a third cow, they are considered to be two ‘degrees’ away from each other (counted as: one degree to the cow they’ve worked with and one more to the other cow). This scales to the general case.

The N (2 <= N <= 300) cows are interested in figuring out which cow has the smallest average degree of separation from all the other cows. excluding herself of course. The cows have made M (1 <= M <= 10000) movies and it is guaranteed that some relationship path exists between every pair of cows.

Input

  • Line 1: Two space-separated integers: N and M

  • Lines 2..M+1: Each input line contains a set of two or more space-separated integers that describes the cows appearing in a single movie. The first integer is the number of cows participating in the described movie, (e.g., Mi); the subsequent Mi integers tell which cows were.

Output

  • Line 1: A single integer that is 100 times the shortest mean degree of separation of any of the cows.

Sample Input

4 2
3 1 2 3
2 3 4

Sample Output

100

Hint

[Cow 3 has worked with all the other cows and thus has degrees of separation: 1, 1, and 1 – a mean of 1.00 .]


中文题意:

数学课上,WNJXYK忽然发现人缘也是可以被量化的,我们用一个人到其他所有人的平均距离来量化计算。
在这里定义人与人的距离:

1.自己与自己的距离为0
2.如果A和B属于同一个小团体,那么他们之间的距离为1
3.如果A与B属于一个小团体,B与C属于一个小团体,且A与C不同属于任何一个小团体,那么A与C的距离为2(A联系C,经过B、C两个人)
4.以此类推

班里有N个人 (2 <= N <= 300),共有M对小团体关系(1 <= M <= 10000)。现在,给你所有班级中小团体的信息,问你班里人缘最好的人到其他人的平均距离。(你需要输出平均距离的100倍)

Input

第一行输入两个证书N,M 接下来的M+1行。
每行开头一个整数K表示本小团体大小,然后接下来K个整数表示小团体内学生编号。

Output

输出一行:最小的平均距离*100(程序中请不要使用Float和Double计算,可能会判Wa)

Sample Input

4 2
3 1 2 3
2 3 4

Sample Output

100

解题心得:

  1. 其实就是一个建图的问题,直接将同一个团体里面的人都添加一条边,距离是100,不建立其他的边,枚举每个点跑最短路就行了。

#include <stdio.h>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 310;
int maps[maxn][maxn],Time[maxn],Min = 0x7f7f7f7f;
bool vis[maxn];
int n,m;

void init() {
    int num[10010];
    memset(maps,0,sizeof(maps));
    for(int z=0;z<m;z++) {
        int cnt;
        scanf("%d",&cnt);
        for(int i=0;i<cnt;i++) {
            scanf("%d",&num[i]);
        }
        for(int i=0;i<cnt;i++)
            for(int j=0;j<i;j++) {
                maps[num[i]][num[j]] = maps[num[j]][num[i]] = 100;
            }
    }
}

void spfa(int s) {
    memset(Time,0x7f,sizeof(Time));
    queue <int> qu;
    qu.push(s);
    Time[s] = 0;
    while(!qu.empty()) {
        int now = qu.front(); qu.pop();
        vis[now] = false;
        for(int i=1;i<=n;i++) {
            if(maps[now][i]) {
                if(Time[i] > Time[now] + maps[now][i]) {
                    Time[i] = Time[now] + maps[now][i];
                    if(!vis[i]) {
                        qu.push(i);
                        vis[i] = true;
                    }
                }
            }
        }
    }
}

void get_sum_path() {
    int sum = 0;
    for(int i=1;i<=n;i++) {
        sum += Time[i];
    }
    if(sum < Min)
        Min = sum;
}

int main() {
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=n;i++) {
        spfa(i);
        get_sum_path();
    }
    printf("%d",Min/(n-1));
    return 0;
}
原文地址:https://www.cnblogs.com/GoldenFingers/p/9107150.html