题面在这里
做法:
floyd+DP。
设
w[i][j]
表示
i−j
的最短路,
f[i][j]
表示
i−j
最短路方案数。
转移就是
f[i][j]+=f[i][k]∗f[k][j]
然后再枚举每个点计算一下好了= =
/*************************************************************
Problem: bzoj 1491 [NOI2007]社交网络
User: fengyuan
Language: C++
Result: Accepted
Time: 76 ms
Memory: 1416 kb
Submit_Time: 2017-12-15 23:36:02
*************************************************************/
#include<bits/stdc++.h>
#define rep(i, x, y) for (int i = (x); i <= (y); i ++)
#define down(i, x, y) for (int i = (x); i >= (y); i --)
#define mid ((l+r)/2)
#define lc (o<<1)
#define rc (o<<1|1)
#define pb push_back
#define mp make_pair
#define PII pair<int, int>
#define F first
#define S second
#define B begin()
#define E end()
using namespace std;
typedef long long LL;
//head
const int N = 105;
const int INF = 1e9;
int n, m;
int w[N][N];
LL f[N][N];
int main()
{
scanf("%d%d", &n, &m);
rep(i, 1, n) rep(j, 1, n) if (i != j) w[i][j] = INF;
rep(i, 1, m){
int x, y, z; scanf("%d%d%d", &x, &y, &z);
w[x][y] = w[y][x] = z;
f[x][y] = f[y][x] = 1;
}
rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
if (w[i][k]+w[k][j] < w[i][j]){
w[i][j] = w[i][k]+w[k][j];
f[i][j] = f[i][k]*f[k][j];
} else if (w[i][k]+w[k][j] == w[i][j]) f[i][j] += f[i][k]*f[k][j];
rep(i, 1, n) f[i][i] = 0;
rep(k, 1, n){
double ans = 0;
rep(i, 1, n) rep(j, 1, n){
if (i == k || j == k || i == j) continue;
if (w[i][k]+w[k][j] == w[i][j] && f[i][j] > 0){
ans += f[i][k]/(double)f[i][j]*f[k][j];
}
}
printf("%.3lf\n", ans);
}
return 0;
}