【BZOJ 1491】[NOI2007]社交网络
【链接】 我是链接,点我呀:)
【题意】
【题解】
floyd算法 算出任意两点之间的最短路,以及最短路的条数。 然后三重循环枚举v,s,t就好 看看s到t的最短路径不经过v 经过的话增加答案贡献 $O(n^3)$【代码】
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N = 100;
int n,m;
ll dis[N+10][N+10],num[N+10][N+10];
int main()
{
memset(dis,255,sizeof dis);
scanf("%d%d",&n,&m);
for (int i = 1;i <= m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
dis[x][y] = dis[y][x] = z;
num[x][y] = 1,num[y][x] = 1;
}
for (int k = 1;k <= n;k++)
for (int i = 1;i <= n;i++)
if (i!=k)
for (int j = 1;j <= n;j++)
if (k!=j && j!=i){
if (dis[i][k]==-1 || dis[k][j]==-1) continue;
if (dis[i][j]==-1 || dis[i][j] > dis[i][k]+dis[k][j]){
dis[i][j] = dis[i][k]+dis[k][j];
num[i][j] = num[i][k]*num[k][j];
}else if (dis[i][j]==dis[i][k]+dis[k][j]){
num[i][j]+=num[i][k]*num[k][j];
}
}
for (int v = 1;v<= n;v++){
double ans = 0;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)
if (i!=v && j!=v){
if (dis[i][v]!=-1 && dis[v][j]!=-1 && dis[i][v]+dis[v][j]==dis[i][j]){
ll temp = num[i][v]*num[v][j];
ll temp2 = num[i][j];
ans += (temp*1.0)/(temp2*1.0);
}
}
printf("%.3f\n",ans);
}
return 0;
}