【最短路】蒜厂年会

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

每两个员工之间都有一个亲密度。在同一个项目工作过的员工之间的亲密度为 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题 不过需要注意小细节问题 
代码和注释

 

转载于:https://www.cnblogs.com/OIerLYF/p/6056760.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值