P2047 [NOI2007] 社交网络 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P2047题目大意:
x = 经过k节点从a到b的最短路数目 / 从a到b的最短路数目,把图中所有合题的x累加求和
注意:
1,dis的无穷初始化和edge的初始化问题
2.注意第一个三层循环的k相当于中继站求最短路的作用,第二个是统计经过k节点从a到b的最短路数目求ans
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxN = 110;
const int INF = 0x3f3f3f3f;
int dis[maxN][maxN];
int edge[maxN][maxN];
double ans[maxN];
void solve()
{
int n,m;
scanf("%lld%lld", &n, &m);
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=n;j++)
{
G[i][j] = dis[i][j] = INF;
}
}
for(int i = 1;i<=m;i++)
{
int a,b,c; scanf("%lld%lld%lld", &a, &b, &c);
dis[a][b] = dis[b][a]= c;
edge[a][b] = edge[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( dis[i][k]==INF && dis[k][j]==INF )
continue;
if( dis[i][k]+dis[k][j]<dis[i][j] )
{
dis[i][j] = dis[i][k] + dis[k][j];
edge[i][j] = edge[i][k] * edge[k][j];
}
else if( dis[i][k]+dis[k][j]==dis[i][j] )
edge[i][j] = edge[i][j] + edge[i][k]*edge[k][j];
}
}
}
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)continue;
if( dis[i][k]+dis[k][j]==dis[i][j] )
ans[k] = ans[k] + (double)( 1.0*edge[i][k]*edge[k][j]
)/(double)edge[i][j];
}
}
}
for(int i = 1;i<=n;i++)
printf("%.3lf\n",ans[i]);
}
signed main()
{
int _ = 1;
// scanf("%d", &_);
while( _-- )
solve();
return 0;
}