bzoj1491 [noi2007]社交網路
看到資料規模,最先想到的是floyd,但在統計方案的地方卡住了。瀏覽了幾篇題解,得到了一點啟示。
在floyd過程中,列舉k為中轉點:如果當前需要更新,那麼經過k的最短路條數附初始值為兩邊(i-k和k-j)的條數之積(乘法原理);如果恰巧當前就是一條最短路,那麼此點最短路數加上這一(i,j)的最短路數(乘法原理,類似地)。
可以邊更新最短路邊統計最短路個數,也可以先求出最短路,再列舉各點和起止點統計最短路數,本質上沒啥區別。
floyd結束後,列舉k為當前點,列舉(i,j)為起止點,根據公式可以直接求出答案。
如果用f[i][j]記錄(i,j)路徑最短路數,ans[v]表示v點的答案,公式可以改寫為: i(
v)=∑
i≠v,
j≠vf
[i][
v]∗f
[v][
j]f[
i][j
];f[
i][j
]=∑k
∈pat
h(i,
j)f[
i][k
]∗f[
k][j
]f[i
][j]
i (v
)=∑i
≠v,j
≠vf[
i][v
]∗f[
v][j
]f[i
][j]
;f[i
][j]
=∑k∈
path
(i,j
)f[i
][k]
∗f[k
][j]
f[i]
[j
]此題核心在於處理方案,類似於dp套dp,但又不是嚴格的dp。
值得注意的是,在加邊的時候f要先賦初值1,否則,如果兩點間的最短路就是這一條邊,那麼可能floyd不會更新(因為列舉時k不與i或j相等),就造成兩次統計答案是某一時刻分母可能為0……
#include
#include
using
namespace
std;
const
int maxn=120,inf=5000000;
int a[maxn][maxn];
double f[maxn][maxn],ans[maxn];
int n,m;
void floyed()
else f[i][j]+=f[i][k]*f[k][j];
}}void dp()
int main()
floyed();
dp();
for(int i=1;i<=n;i++)
printf("%.3lf\n",ans[i]);
return
0;}
noi2007 社交網路
給定乙個由n個點組成的無向圖,求所有點的 v x sum a ne b 其中 c a,b 表示 a,b 這條最短路路徑的條數,c a,b v 表示 a,b 最短路中經過v的最短路的條數。n le 100 這道題要分三個子問題 求出ab距離,求出ab最短路條數,求出ab最短路中,經過v的條數。如果第二...
NOI2007 社交網路
題目 洛谷p2047 bzoj1491 vijos p1591 codevs1796。題目大意 給你一張帶權無向圖。令 c 表示從s到t的不同的最短路的數目,c v 表示經過v從s到t的不同的最短路的數目。則定義 為節點v的重要程度。問每個節點的重要程度 保留3位小數 解題思路 用floyd求出每個...
NOI2007 社交網路
在社交網路 social network 的研究中,我們常常使用圖論概念去解釋一些社會現象。不妨看這樣的乙個問題。在乙個社交圈子裡有n個人,人與人之間有不同程度的關係。我 們將這個關係網路對應到乙個n個結點的無向圖上,兩個不同的人若互相認識,則在他們對應的結點之間連線一條無向邊,並附上乙個正數權值c...