LightOJ 1321 Sending Packets 期望+最短路

Sending Packets LightOJ - 1321

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

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

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

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

代码如下:

#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;
}

在这里插入图片描述

发布了37 篇原创文章 · 获赞 0 · 访问量 308
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览