题意:给N头牛,M个电影,牛1牛2一起看过电影,两者距离为1,如果牛3没有和牛1看过,和牛2看过,牛3牛2距离为1,牛3牛1 距离为2;找出与其他牛平均距离最小的牛,输出最小平均距离*100
思路:弗洛伊德算法,不要刻意分组,在一组相当于之间有权值为1的边,不在一组为间接相连
#include <cstdio>
#include <iostream>
#include <fstream>
const int MAX = 310;
const int INF = 1e6;
using namespace std;
int n, m, im;
int a[MAX][MAX];
int d[MAX][MAX];
int ans, sum;
//在电影内建立联系
void CreatGraph(int x){
for(int i=0; i<im; i++){
for(int j=i+1; j<im; j++){
d[a[x][i]][a[x][j]] = 1;
d[a[x][j]][a[x][i]] = 1;
}
}
}
//Floyd求最短路径
void Floyd(){
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
for(int k=0; k<=n; k++)
d[j][k] = min(d[j][k], d[j][i]+d[i][k]);
ans = INF;
for(int i=1; i<=n; i++){
sum = 0;
for(int j=1; j<=n; j++){
sum = sum + d[i][j];
}
ans = min(ans, sum);
}
cout << ans*100/(n-1) << endl;
}
//测试函数
int main(){
ifstream cin ("D:\\钢铁程序员\\程序数据\\063奶牛的六度空间.txt");//从文件读取数据流,省去手动输入的麻烦
if(!cin){//读取如果失败
cout << "ERROR" << endl;
}
cin >> n >> m;
//初始化
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++){
if(i == j)
d[i][j] = 0;
else
d[i][j] = INF;
}
//建立联系
for(int i=0; i<m; i++){
cin >> im;
for(int j=0; j<im; j++){
cin >> a[i][j];
}
CreatGraph(i);
}
//求ans
Floyd();
cin.close();//打开文件以后要关闭
return 0;
}