Lightoj 1321 Sending Packets(Bellman-Ford)

题意

给定一个无向图,边的权值为小于1的小数,表示通过这条边的数据成功传输到另一边的可能性,0.8表示有百分之八十的可能性传输过去。问你从起点到终点,最大的传输成功率多大。

分析

根据题意,相当于求一个最长路,dijkstra有点难写,直接用bellman-ford,因为边权值都是小于1的,所以更新操作用的乘法永远是越来越小的,我们刚好要最大的。所以比较方便就能处理出来,然后得出最大的传输成功率以后结合题意中的其他要求进行简单的运算就能得出答案了。

代码

#define rep(x,y,z) for(int x=y;x<z;x++)
#define drep(x,y,z) for(int x=y;x>=z;x--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define clr(x,y) memset(x,y,sizeof(x))
#define fi first
#define se second

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

const int N = 110;

vector<pair<pair<int,int>,double> > edge;
double val[N];
double dp[N][N];

void init(){
    edge.clear();
    clr(val,0);
    clr(dp,0);
}

void read(int m){
    rep(i,0,m){
        int u , v , w;
        scanf("%d %d %d",&u,&v,&w);
        edge.pb(mp(mp(u,v),double(w)/100.0));
        edge.pb(mp(mp(v,u),double(w)/100.0));
    }
}

double slove(int n){
    val[0] = 1;
    int size = edge.size();
    while(1){
        bool ok = 0;
        rep(i,0,size){
            int u = edge[i].fi.fi;
            int v = edge[i].fi.se;
            double w = edge[i].se;

            if(val[u] * w > val[v]){
                ok = 1;
                val[v] = val[u] * w;

            }
        }
        if(!ok) break;
    }
    return val[n - 1];
}

int main(){
    int t;
    scanf("%d",&t);
    rep(tt,1,t+1){
        int n , m , s , k;
        scanf("%d %d %d %d",&n,&m,&s,&k);
        init();
        read(m);
        double ans = slove(n);
        //
        ans = (k / ans) * 2 * s;
        //
        printf("Case %d: %lf\n",tt,ans);
    }

    return 0;
}
时间: 2024-10-26 12:41:16

Lightoj 1321 Sending Packets(Bellman-Ford)的相关文章

lightoj 1321 Sending Packets (概率)

从0到n-1需要传输s个包,传输的时候每条边安全到达的概率为pi,每次传输的时间为2K,如果在传输时候没有安全到达,则要重新传送,求最小的传送时间 题意:http://www.lightoj.com/volume_showproblem.php?problem=1321 只要成功传输一次,剩下的就能快速传输,不计时间.那么求最小时间期望就等同于求最大的一次性传输成功的概率p,那么传输成功的最小次数的期望 就是1/p,那么最小的时间期望就是 1/p * 2 * k * s. #include<cs

ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可以求得一点到任意一点经过一条边的最短路,遍历两次可以求得一点到任意一点经过两条边的最短路...如 此反复,当遍历m次所有边后,则可以求得一点到任意一点经过m条边后的最短路(有点类似离散数学中邻接矩阵的连通性判定) POJ1556-The Doors 初学就先看POJ2240吧 题意:求从(0,5)到

POJ 1860 Currency Exchange (Bellman ford)

Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22405   Accepted: 8095 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and pe

Bellman - Ford 算法解决最短路径问题

Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力不从心了,而Bellman - Ford算法可以解决这种问题. Bellman - Ford 算法可以处理路径权值为负数时的单源最短路径问题.设想可以从图中找到一个环路且这个环路中所有路径的权值之和为负.那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去.如果不处理这个负环路,程序就会永远运

Bellman—Ford算法思想

---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G运行Bellman—Ford算法的结果是一个布尔值,表明图中是否存在着一个从源点s可达的负权回路.若存在负权回路,单源点最短路径问题无解:若不存在这样的回路,算法将给出从源点s到图G的任意顶点v的最短路径值d[v] Bellman—Ford算法流程 分为三个阶段: (1)初始化:将除源点外的所有顶点

ACM/ICPC 之 Bellman Ford练习题(ZOJ1791(POJ1613))

这道题稍复杂一些,需要掌握字符串输入的处理+限制了可以行走的时间. ZOJ1791(POJ1613)-Cave Raider //限制行走时间的最短路 //POJ1613-ZOJ1791 //Time:16Ms Memory:324K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAX 505 #d

poj 3259 Wormholes (BELLman—FOrd算法)(邻接矩阵表示)

http://poj.org/problem?id=3259 之前一开始 ,没做出来,搁置了好几天才看见bug所在.所以今天a掉了 ,把代码贴出来,这个使用邻接矩阵表示的 ,下一篇用邻接表可以提高效率. #include<iostream> #include<queue> #include<stdio.h> #include<string.h> using namespace std; const int INF=600; int G[INF][INF];

Bellman ford 最短路径算法

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" /> 下表记录S到每一个节点的距离: 第一次迭代, S->A = 4 ,由于S->A眼下为INF.因此更新MIN(S->A)为4 S->B = 6.由于S->B眼下为INF.因此更新MIN(S->B)为6 S->C

最短路径——Bellman Ford算法(C++)

源代码: #include<cstdio>#include<cstring>int m(1),n,k,i[1001],x[1001],y[1001],f[1001];int main(){ scanf("%d%d",&n,&k); for (int a=1;a<=n;a++) for (int b=1;b<=n;b++) { scanf("%d",&i[m]); if (i[m]!=-1) { x[m]=a