博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
计蒜客NOIP模拟赛(3) D1T2 信息传递
阅读量:4931 次
发布时间:2019-06-11

本文共 2450 字,大约阅读时间需要 8 分钟。

一个数据包在一个无向网络中传递。在时刻0,该数据包将依照特定的概率随机抵达网络中的某个节点。

网络可以看做一张完全带权无向图,包含N个节点,若t时刻数据包在节点i,则在t+1时刻,数据包被传递到节点j的概率是

d(i,j)/(∑kd(i,k))

其中d(i,j)表示节点i到节点j的最短路径的长度。在传递到下一个节点后,该数据包会自动删除在当前节点的备份。
现在,给定数据包0时刻在每个节点的概率和网络的每条边权。求T时刻数据包在每个节点的概率。
输入格式
第一行两个整数N和T。
第二行N个实数,表示0时刻数据包在每个节点的概率(保证概率加起来为1)。
接下来N行每行N个整数,第i行第j个数表示节点i和节点j之间的边权。
保证第i行第i个数为0且第i行第j个数等于第j行第i个数。
输出格式
输出共N行,第i行表示T时刻数据包在节点i的概率,保留六位小数。
数据范围与约定
对于50%的数据,T≤20。
对于100%的数据,N≤200,T≤10^9。保证对于每个点d的和值在int范围。
样例输入
3 2
0 1 0
0 1 4
1 0 2
4 2 0
样例输出
0.400000
0.350000
0.250000
首先列出dp式

f[t][v]=∑uf[t-1][u]*(d(u,v)/(∑kd(u,k)))

显然含有矩阵快速幂的特点,写出矩阵,假设n=3

0                             d(1,2)/(∑kd(1,k))    d(1,3)/(∑kd(1,k))

d(2,1)/(∑kd(2,k))     0                            d(2,3)/(∑kd(2,k))

d(3,1)/(∑kd(3,k))     d(3,2)/(∑kd(3,k))    0

d的话直接弗洛伊德

转移矩阵Mat[i][j]=d(i,j)/(kd(i,k))

1 #include
2 #include
3 #include
4 #include
5 using namespace std; 6 struct Matrix 7 { 8 double a[302][302]; 9 }Mat,pre,st,ans;10 int n,T;11 double s[301],map[301][301];12 Matrix operator *(const Matrix &x,const Matrix &y)13 {14 Matrix res;15 int i,j,k;16 memset(res.a,0,sizeof(res.a));17 for (i=1;i<=n;i++)18 {19 for (j=1;j<=n;j++)20 {21 for (k=1;k<=n;k++)22 {23 res.a[i][j]+=x.a[i][k]*y.a[k][j];24 }25 }26 }27 return res;28 }29 void qpow(int x)30 {
int i;31 for (i=1;i<=n;i++)32 ans.a[i][i]=1;33 while (x)34 {35 if (x&1) ans=ans*Mat;36 Mat=Mat*Mat;37 x/=2;38 }39 }40 int main()41 {
int i,j,k;42 cin>>n>>T;43 memset(pre.a,0,sizeof(pre.a));44 memset(Mat.a,0,sizeof(Mat.a));45 for (i=1;i<=n;i++)46 scanf("%lf",&pre.a[1][i]);47 for (i=1;i<=n;i++)48 {49 for (j=1;j<=n;j++)50 {51 scanf("%lf",&map[i][j]);52 }53 }54 for (k=1;k<=n;k++)55 for (i=1;i<=n;i++)56 if (i!=k)57 for (j=1;j<=n;j++)58 if (i!=j&&k!=j)59 map[i][j]=min(map[i][j],map[i][k]+map[k][j]);60 for (i=1;i<=n;i++)61 for (j=1;j<=n;j++)62 if (i!=j) s[i]+=map[i][j];63 for (i=1;i<=n;i++)64 {
for (j=1;j<=n;j++)65 if (i!=j)66 Mat.a[j][i]=map[j][i]/s[j];67 }68 qpow(T);69 ans=pre*ans;70 for (i=1;i<=n;i++)71 printf("%.6lf\n",ans.a[1][i]);72 }

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/7506291.html

你可能感兴趣的文章
3.每周总结
查看>>
应用提交 App Store 上架被拒绝
查看>>
Android实现异步处理 -- HTTP请求
查看>>
数据清空js清空div里的数据问题
查看>>
Fortran中的指针使用
查看>>
移动终端app测试点总结
查看>>
14-6-27&28自学内容小结
查看>>
JSP
查看>>
---
查看>>
(第一组_GNS3)自反ACl
查看>>
hdu--1258--Sum It Up(Map水过)
查看>>
Spring @DeclareParents 的扩展应用实例
查看>>
VS2012更新Update1后帮助查看器无法打开
查看>>
【Weiss】【第03章】练习3.9:大整数运算包
查看>>
Android 文件的读取和写入
查看>>
机器学习-加权采样算法简介
查看>>
高校表白APP-冲刺第四天
查看>>
outlook 设置163邮箱
查看>>
Flash设置(各种版本浏览器包括低版本IE)
查看>>
mysql优化——show processlist命令详解
查看>>