图论蒜厂年会

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论蒜厂年会相关的知识,希望对你有一定的参考价值。

蒜厂要开年会了,所有的员工都要参加。

每两个员工之间都有一个亲密度。在同一个项目工作过的员工之间的亲密度为 11。如果 A 和 B、B 和 C 均在同一个项目中工作过,而 A 和 C 没有,那么 A 和 C 之间的亲密度为 1+1=21+1=2。

同理,如果 A 和 B 之间的亲密度为 xx,B 和 C 之间的亲密度为 yy,则 A 和 C 之间的一种 可能亲密度 为 x+yx+y。两个人之间的 亲密度 为所有的 可能亲密度 之中的 最小值。

因为蒜厂里员工之间非常有爱,所以 保证每两个员工之间都可以算出一个亲密度。

现在有一个名单,一直蒜厂在这一年一共进行过 MM 个项目,NN 名员工都想知道自己与其他所有员工的亲密度的平均值,现在你需要找出所有员工中,与其他所有员工 亲密度平均值 最小的员工,即和其他所有员工最亲密的一名员工,来担任这次年会的主持人。

输入格式

一行两个整数 NN 和 MM,(1\\leq M\\leq 10000,2\\leq N\\leq 300)(1M10000,2N300)。

接下来 MM 行,表示 MM 个项目名单,每行第一个整数表示参加这一个项目的员工人数,后面是这些员工的编号,所有员工的编号从 11 开始计数。

输出格式

一行一个整数,为最小的亲密度平均值乘 100100 以后向下取整。

样例输入

4 2
3 1 2 3
2 3 4

样例输出

100

这个题差不多算是一个裸的Floyd多源最短路问题,但是有些细节问题需要特别注意一下。

首先是在读入的时候,只要是共同工作过他们的权值都是1.

其次是小技巧,最后算那个加和值的时候,先不要*100/n啊啥的,放到最后算。可以略微的优化

技术分享
#include <iostream>
using namespace std;
int f,g,h=1,q,n,m,a[301][301],total,da=10000,s[1001];
int inf=999999;
int main(){
    cin>>n>>m;  //n个员工 m个项目 
    for(int j=1;j<=n;j++){   //初始化边 
        for(int k=1;k<=n;k++){
            if(j == k) a[j][k]=0;
            else a[j][k]=inf;
        }
    }
    for(int i=1;i<=m;i++){  //把每个项目 工作的人 权重赋1 
        cin>>q;
        for(int j=0;j<q;++j) cin>>s[j];
        for(int j=0;j<q;++j)
            for(int b=1;b<q;++b)
                a[s[j]][s[b]]=1;
    }
    for(int k=1;k<=n;k++) //Floyd核心语句 
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(a[i][j] > a[i][k]+a[k][j] &&  a[i][k]<inf && a[k][j]<inf)
                    a[i][j]=a[i][k]+a[k][j];
    for(int i=1;i<=n;i++){  //把每个点的所有边先进行加和 求出最小的那个 
        for(int j=1;j<=n;j++){
            total = a[i][j] + total;
        }
        if(total < da )    da = total ;
        total = 0;
    }    
    da = da * 100 / n;  //最小的那个 先*100 再除去n 
    cout<<da<<endl;//输出  
    return 0;
}//差不多就是一个裸的Floyd题 不过需要注意小细节问题 
代码和注释

 

以上是关于图论蒜厂年会的主要内容,如果未能解决你的问题,请参考以下文章

计蒜课/百度的年会游戏(枚举)

年会的具体流程

公司年会要抽奖,那些抽奖的小程序是在那里获取的呀?

图论一笔画问题代码基本框架

图论源代码——数据结构课堂作业

[年会]程序员的年会表演:《对你爱不完》全舞蹈解释