LightOJ 1321 Sending Packets 期望+最短路

Sending Packets LightOJ - 1321

n n n 个路由器,编号为 0 ∼ n − 1 0\sim n-1 0n1 ,路由器之间有无向边 u i , v i u_i,v_i ui,vi ,每条边成功传输数据的概率是 p i p_i pi,从 0 0 0 传数据给 n − 1 n-1 n1,每次传送 1KB,总共 s KB,成功的概率为链路上所有边的 p i p_i pi 的乘积, 0 0 0 处在等待时间 2 K 2K 2K 之后假如收到了确认信号(确认信号不会丢失),那就发送下一 KB,否则重新发送当前 KB,求发送完所有数据的期望时间。

首先用最短路径算法求出一次通过的最大概率 p p p,设成功发送 1 KB 所需要的期望时间是 E E E,则:

E = 2 k ⋅ p + ( 1 − p ) ( 2 k + E ) E = 2 k p \begin{aligned} E&=2k\cdot p+(1-p)(2k+E)\\ E&=\frac{2k}{p} \end{aligned} EE=2kp+(1p)(2k+E)=p2k

则传送 s KB 需要的时间就是 s E sE sE

代码如下:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
//#define WINE
#define MAXN 105
#define MAXM 20005
using namespace std;
int T,iCase,n,m,s,k,u,v,head[MAXN],cnt;
double p,dis[MAXN];bool vis[MAXN];
struct Edge{
    int to,nxt;
    double p;
}edge[MAXM];
void addedge(int u,int v,double p){
    edge[cnt].to=v;
    edge[cnt].p=p;
    edge[cnt].nxt=head[u];
    head[u]=cnt++;
}
struct Node{
    int v;double p;
    Node(){}
    Node(int _v,double _p):v(_v),p(_p){}
    bool operator<(const Node&b)const{
        return p<b.p;
    }
};
void dijkstra(){
    priority_queue<Node> q;
    memset(vis,false,sizeof(vis));
    memset(dis,0,sizeof(dis));
    q.push(Node(0,1));
    dis[0]=1;
    while(!q.empty()){
        Node t=q.top();q.pop();
        int u=t.v;double p=t.p;
        if(vis[u])continue;vis[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;double w=edge[i].p;
            if(p*w>dis[v]){
                dis[v]=p*w;
                q.push(Node(v,dis[v]));
            }
        }
    }
}
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&T);
    while(T--){
        memset(head,-1,sizeof(head));cnt=0;
        scanf("%d%d%d%d",&n,&m,&s,&k);
        for(int i=0;i<m;i++){
            scanf("%d%d%lf",&u,&v,&p);p/=100;
            addedge(u,v,p);addedge(v,u,p);
        }
        dijkstra();
        printf("Case %d: %.8lf\n",++iCase,2*k/dis[n-1]*s);
    }
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值