题意:奶牛拍一系列电影,n头牛拍m部电影,同一部电影种的搭档们距离为1,求最小距离?
思路:Floyd 图 最短路径
- 存图: 初始化图
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
f[i][j] = INF;
f[i][i] = 0;
} - 存图:
for (int i = 0; i < k; i++)
{
scanf("%d", &a[i]);
for (int j = 0; j < i; j++)
f[a[i]][a[j]] = f[a[j]][a[i]] = 1;
} - floyd算法:
void floyd()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
if (f[j][k] > (f[j][i] + f[i][k]))
f[j][k] = f[j][i] + f[i][k];
} 解释一下a[i][j]表示i到j的距离 a[i][k]+a[k][j]表示 i到k到j的距离 - 找到其中的一条最短路径即可
解决问题的代码:
#include <iostream> #include <cstdio> using namespace std; #define INF 1<<29 #define maxn 305 int f[maxn][maxn]; int a[maxn]; int n, m; void floyd() { for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) if (f[j][k] > (f[j][i] + f[i][k])) f[j][k] = f[j][i] + f[i][k]; } int main() { while (scanf("%d%d", &n, &m) != EOF) { for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) f[i][j] = INF; f[i][i] = 0; } while (m--) { int k; scanf("%d", &k); for (int i = 0; i < k; i++) { scanf("%d", &a[i]); for (int j = 0; j < i; j++) f[a[i]][a[j]] = f[a[j]][a[i]] = 1; } } floyd(); int ans = INF; for (int i = 1; i <= n; i++) { int res = 0; for (int j = 1; j <= n; j++) res += f[i][j]; if (res < ans) ans = res; } printf("%d ", ans * 100 / (n - 1)); } return 0; }