P2047 [NOI2007] 社交网络
思路
题目中会求到起点
s
s
s到终点
t
t
t的最短路,并且
n
n
n只有
100
100
100,因此想到了
F
l
o
y
d
Floyd
Floyd
那么
F
l
o
y
d
Floyd
Floyd如何更新路径条数呢
dis[i][j]从i点到j点的最短路
sum[i][j]从i点到j点的最短路条数
如果dis[i][k]+dis[k][j]等于dis[i][j]那么sum[i][j]的条数会增加(长短一样),根据乘法原理,sum[i][j]加上sum[i][k]*sum[k][j]
如果小于的话,dis要更新,sum变成sum[i][k]*sum[k][j]
最后该怎么统计,如下:
每一个k点,枚举每一个i和j,如果dis[i][k]+dis[k][j]等于dis[i][j],那么就加上sum[i][k]*sum[k][j]除以sum[i][j](i、j的总条数和经过k的条数)
代码
#include<iostream>
#include<cstring>
using namespace std;
const int N=110,INF=0x3f3f3f3f;
using ll=long long;
int n,m;
ll dist[N][N],sum[N][N];
int main(){
cin>>n>>m;
memset(dist,INF,sizeof dist);
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
dist[a][b]=dist[b][a]=c;
sum[a][b]=sum[b][a]=1;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&j!=k&&i!=k){
if(dist[i][k]+dist[k][j]==dist[i][j]){
sum[i][j]+=sum[i][k]*sum[k][j];
}
else if(dist[i][k]+dist[k][j]<dist[i][j]){
dist[i][j]=dist[i][k]+dist[k][j];
sum[i][j]=sum[i][k]*sum[k][j];
}
}
for(int k=1;k<=n;k++){
double ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&j!=k&&k!=i&&dist[i][j]==dist[i][k]+dist[k][j]) ans+=(double)sum[i][k]*sum[k][j]/sum[i][j];
printf("%.3f\n",ans);
}
return 0;
}
-转载,原作者