BZOJ-1491 社交网络 FLoyd+乱搞

时间:2023-06-06 12:24:02
感觉这两天一直在做乱搞的题。。。

1491: [NOI2007]社交网络

Time Limit: 10 Sec Memory Limit: 64 MB

Submit: 1279 Solved: 732

[Submit][Status][Discuss]

Description

BZOJ-1491   社交网络    FLoyd+乱搞

Input

BZOJ-1491   社交网络    FLoyd+乱搞

Output

输出文件包括n 行,每行一个实数,精确到小数点后3 位。第i 行的实数表 示结点i 在社交网络中的重要程度。

Sample Input

4 4

1 2 1

2 3 1

3 4 1

4 1 1

Sample Output

1.000

1.000

1.000

1.000

HINT

BZOJ-1491   社交网络    FLoyd+乱搞

为1

BZOJ-1491   社交网络    FLoyd+乱搞

Source

两个floyd,第一个求出最短路径,并记录road【i】【k】和road【k】【j】根据乘法原理,经过k的从i到j的最短路径即为road【i】【k】*road【k】【j】(我会说一开始打成+还死活没看见吗。。。。)然后统计输出即可

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9'){if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} int n,m;
int edge[200][200];
long long road[200][200];
double ans[200];
#define inf 1000000001 void floyd()
{
for (int k=1; k<=n; k++)
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
{
if (edge[i][j]>edge[i][k]+edge[k][j])
{
edge[i][j]=edge[i][k]+edge[k][j];
road[i][j]=0;
}
if (edge[i][j]==edge[i][k]+edge[k][j])
road[i][j]+=road[i][k]*road[k][j];
}
} void floyed()
{
for (int i=1; i<=n; i++) road[i][i]=0;
for (int k=1; k<=n; k++)
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
if (edge[i][j]==edge[i][k]+edge[k][j] && road[i][j]>0)
ans[k]+=(double)road[i][k]*(double)road[k][j]/(double)road[i][j];
} int main()
{
n=read();m=read();
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
edge[i][j]=inf;
for (int i=1; i<=m; i++)
{
int u=read(),v=read(),c=read();
edge[u][v]=edge[v][u]=c;
road[u][v]=road[v][u]=1;
}
floyd();floyed();
for (int i=1; i<=n; i++)
printf("%.3lf\n",ans[i]);
return 0;
}