bzoj 1491: [NOI 2007]社交网络
这道题一开始自己本来想出来了。。
结果自己又把自己推翻了。。于是看题解和自己一样。
还好刘教授帮我解释了一下floyd对于一条最短路只会判一次在K=这条路径上最大的那个点的时候。
后面又因为滥用memset(f,127,sizeof(f))导致f[i][k] + f[j][k]会爆所以wa掉了
喜闻乐见地贴代码:
1 /* 2 ID:WULALA 3 PROB:bzoj1491 4 LANG:C++ 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <algorithm> 9 #include <cmath> 10 #include <iostream> 11 #include <fstream> 12 #include <ctime> 13 #define N 108 14 #define M 15 #define mod 16 #define mid(l,r) ((l+r) >> 1) 17 #define INF 0x7ffffff 18 using namespace std; 19 20 long long n,m,f[N][N],sum[N][N]; 21 double w[N]; 22 23 void init() 24 { 25 scanf("%lld%lld",&n,&m); 26 for (int i = 1;i <= n;i++) 27 for (int j = 1;j <= n;j++) 28 sum[i][j] = 1,f[i][j] = INF; 29 for (int i = 1;i <= n;i++) f[i][i] = 0; 30 for (int i = 1;i <= m;i++) 31 { 32 int a,b,c; 33 scanf("%d%d%d",&a,&b,&c); 34 f[a][b] = f[b][a] = c; 35 } 36 } 37 38 void floyd() 39 { 40 for (int k = 1;k <= n;k++) 41 for (int i = 1;i <= n;i++) 42 for (int j = 1;j <= n;j++) 43 { 44 if (k == i||i == j||j == k) continue; 45 if (f[i][j] == f[i][k] + f[k][j]) sum[i][j] += sum[i][k] * sum[k][j]; 46 else if (f[i][j] > f[i][k] + f[k][j]) f[i][j] = f[i][k] + f[k][j],sum[i][j] = sum[i][k] * sum[k][j]; 47 } 48 } 49 50 void work() 51 { 52 for (int k = 1;k <= n;k++) 53 for (int i = 1;i <= n;i++) 54 for (int j = 1;j <= n;j++) 55 { 56 if (k == i||i == j||j == k) continue; 57 if (f[i][j] == f[i][k] + f[k][j]) 58 w[k] += (double)(sum[i][k] * sum[k][j]) / (double)(sum[i][j]); 59 } 60 } 61 62 int main() 63 { 64 init(); 65 floyd(); 66 work(); 67 for (int i = 1;i <= n;i++) 68 printf("%.3lf\n",w[i]); 69 return 0; 70 }