NOI2007 社交网络

传送门


%%%\(\sf{ZYD\;\;TQL}\)


看数据范围应该能想到\(floyd\)

第一步用\(floyd\)预处理出最短路,第二部比较难想(ZYD TQL),我们依旧可以用\(floyd\)来处理,第三步处理答案依旧可以用\(floyd\)……

个人感觉代码比较好理解,但是思路真的不好想。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long int dis[110][110],vis[110][110];
double ans[110];
int read(){
    int k=0; char c=getchar();
    for(;c<'0'||c>'9';) c=getchar();
    for(;c>='0'&&c<='9';c=getchar())
      k=k*10+c-48;
    return k;
}
int main(){
    int n=read(),m=read();
    memset(dis,127/3,sizeof(dis));
    //for(int i=1;i<=n;i++) dis[i][i]=0;
    for(int i=1;i<=m;i++){
        int x=read(),y=read(),z=read();
        dis[x][y]=dis[y][x]=z;
        vis[x][y]=vis[y][x]=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][j]>dis[i][k]+dis[k][j]){
                vis[i][j]=vis[i][k]*vis[k][j];
                dis[i][j]=dis[i][k]+dis[k][j];
            }
            else if(dis[i][j]==dis[i][k]+dis[k][j])
                vis[i][j]+=vis[i][k]*vis[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&&dis[i][j]==dis[i][k]+dis[k][j])
                ans[k]+=(double)(vis[i][k]*vis[k][j])/(double)vis[i][j];
        }
    for(int i=1;i<=n;i++) printf("%.3lf\n",ans[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wxl-Ezio/p/9507893.html