弗洛伊德算法模板
可以求得任意两点之间的最短路问题
1 int d[maxn][maxn];//d[st][en]表示边e = {u,v}的权值(不存在时设为INF,d[i][j] = 0) 2 int V;//顶点的个数 3 4 void Floyd() 5 { 6 for(int k = 0; k < V; k++) 7 for(int i = 0; i < V; i++) 8 for(int j = 0; j < V; j++) 9 { 10 d[i][j] = min(d[i][k] + d[k][j],d[i][j]); 11 } 12 }
对于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会将误差放大)
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <queue> 4 #include <stack> 5 #include <cstdio> 6 #include <string> 7 #include <cstring> 8 #include <sstream> 9 #include <cmath> 10 #define INF 0x3f3f3f3f 11 #define mod 1000000007; 12 #define FRE() freopen("in.txt","r",stdin) 13 using namespace std; 14 const int maxn = 305; 15 int n,m,ans; 16 int cow[maxn][maxn],temp[maxn]; 17 18 void Floyd() 19 { 20 for(int k = 1; k <= n; k++) 21 for(int i = 1; i <= n; i++) 22 for(int j = 1; j <= n; j++) 23 { 24 cow[i][j] = min(cow[i][j],cow[i][k] + cow[k][j]); 25 } 26 } 27 28 29 30 int main() 31 { 32 //FRE(); 33 while(scanf("%d%d",&n,&m) != EOF) 34 { 35 memset(cow,INF,sizeof(cow)); 36 for(int j = 0; j < maxn; j++) 37 { 38 cow[j][j] = 0; 39 } 40 int t; 41 while(m--) 42 { 43 scanf("%d",&t); 44 for(int i = 0; i < t; i++) 45 { 46 scanf("%d",&temp[i]); 47 } 48 for(int i = 0; i < t; i++) 49 for(int j = i+1; j < t; j++) 50 { 51 int x = temp[i],y = temp[j]; 52 cow[x][y] = 1; 53 cow[y][x] = 1; 54 } 55 } 56 Floyd(); 57 ans = INF; 58 for(int i = 1; i <= n; i++) 59 { 60 int res = 0; 61 for(int j = 1; j <= n; j++) 62 { 63 res += cow[i][j]; 64 } 65 ans = min(ans, res*100/(n-1)); 66 } 67 printf("%d\n",ans); 68 } 69 return 0; 70 }