可以求得任意两点之间的最短路问题
int d[maxn][maxn];//d[st][en]表示边e = {u,v}的权值(不存在时设为INF,d[i][j] = 0)
int V;//顶点的个数
void Floyd()
{
for(int k = 0; k < V; k++)
for(int i = 0; i < V; i++)
for(int j = 0; j < V; j++)
{
d[i][j] = min(d[i][k] + d[k][j]);
}
}
对于Floyd算法紫书上给出了这样的提示:
如果使用Floyd算法,在定义INF的大小的时候要注意这个潜在的问题:INF不能定义的太大(如2000000000),否则d[i][k] + d[k][j]会溢出,但是如果INF定义的过小,可能会让长度为INF的边成为最短路的一部分,所以最好估计一下最短路的上限,将INF定义为比这个上限大一点点的数。例如:有1000条边,每条边为1000,那么可以将INF定义为1000001。
附练习题一道:Six Degrees of Cowvin Bacon
题意:有N头牛要拍电影,如果两头牛共拍过一部电影,这两头牛之间的距离就是1,如果这两头牛都与第三头牛一起拍过电影,这两头牛之间距离就是2,问一头牛与其他牛之间的距离的最小平均值,将它乘以100输出。(注意要先乘以100 再除:因为int会让除的时候的精度损失,如果先除再乘以100会将误差放大)
代码:
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cmath>
#define INF 0x3f3f3f3f
#define mod 1000000007;
#define FRE() freopen("in.txt","r",stdin)
using namespace std;
const int maxn = 305;
int n,m,ans;
int cow[maxn][maxn],temp[maxn];
void Floyd()
{
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
cow[i][j] = min(cow[i][k] + cow[k][j]);
}
}
int main()
{
//FRE();
while(scanf("%d%d",&n,&m) != EOF)
{
memset(cow,INF,sizeof(cow));
for(int j = 0; j < maxn; j++)
{
cow[j][j] = 0;
}
int t;
while(m--)
{
scanf("%d",&t);
for(int i = 0; i < t; i++)
{
scanf("%d",&temp[i]);
}
for(int i = 0; i < t; i++)
for(int j = i+1; j < t; j++)
{
int x = temp[i],y = temp[j];
cow[x][y] = 1;
cow[y][x] = 1;
}
}
Floyd();
ans = INF;
for(int i = 1; i <= n; i++)
{
int res = 0;
for(int j = 1; j <= n; j++)
{
res += cow[i][j];
}
ans = min(ans, res*100/(n-1));
}
printf("%d\n",ans);
}
return 0;
}