bzoj1491 社交网络 floyd

       首先,利用floyd得到:a[i][j]表示i->j的最短路,c[i][j]表示i->j的最短路有几条。注意c至少开long long,但是实测double好像更快。

      然后统计答案,对于k,枚举s,t,如果a[s][k]+a[k][t]=a[s][t],那么ans+=c[s][k]*c[k][t]/c[s][t]。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000000
#define N 105
using namespace std;

int n,m,a[N][N]; double c[N][N];
int main(){
	scanf("%d%d",&n,&m); int i,j,k;
	for (i=1; i<=n; i++)
		for (j=1; j<=n; j++) a[i][j]=inf;
	for (i=1; i<=m; i++){
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		a[x][y]=a[y][x]=z; c[x][y]=c[y][x]=1;
	}
	for (k=1; k<=n; k++)
		for (i=1; i<=n; i++) for (j=1; j<=n; j++){
			if (a[i][k]+a[k][j]<a[i][j]){
				a[i][j]=a[i][k]+a[k][j]; c[i][j]=0;
			}
			if (a[i][k]+a[k][j]==a[i][j]) c[i][j]+=c[i][k]*c[k][j];
		}
	for (i=1; i<=n; i++) c[i][i]=0;
	for (k=1; k<=n; k++){
		double ans=0;
		for (i=1; i<=n; i++) for (j=1; j<=n; j++)
			if (a[i][k]+a[k][j]==a[i][j] && c[i][j]){
				ans+=c[i][k]*c[k][j]/c[i][j];
			}
		printf("%.3f\n",ans);
	}
	return 0;
}

by lych
2016.2.16

你可能感兴趣的:(图论,最短路,floyd)