问题 : 信道安全
时间限制: 2 Sec 内存限制: 128 MB提交: 7 解决: 4
[ 提交][ 状态]
题目描述
Alpha 机构有自己的一套网络系统进行信息传送。情报员 A 位于节点 1,他准备将一份情报
发送给位于节点 n 的情报部门。可是由于最近国际纷争,战事不断,很多信道都有可能被遭到监
视或破坏。
经过测试分析,Alpha 情报系统获得了网络中每段信道安全可靠性的概率,情报员 A 决定选
择一条安全性最高,即概率最大的信道路径进行发送情报。
你能帮情报员 A 找到这条信道路径吗?
输入
第一行: T 表示以下有 T 组测试数据 ( 1≤T ≤8 )
对每组测试数据:
第一行: n m 分别表示网络中的节点数和信道数 (1<=n<=10000,1<=m<=50000)
接下来有 m 行, 每行包含三个整数 i,j,p,表示节点 i 与节点 j 之间有一条信道,其信
道安全可靠性的概率为 p%。 ( 1<=i, j<=n 1<=p<=100)
输出
每组测试数据,输出占一行,一个实数 即情报传送到达节点 n 的最高概率,精确到小数点后
6 位。
样例输入
1
5 7
5 2 100
3 5 80
2 3 70
2 1 50
3 4 90
4 1 85
3 1 70
样例输出
61.200000
提示
题意概况:
在一个传递信息的网络中有n个节点,m条信道。但是这些信道发送信息的成功率是不同的,问把一条信息从1节点传送到n节点最高的成功率是多少?
解题思路:
可以看出这是一道最短的题目,但是用Dijkstra数据太大肯定是没法写的,但是当时没仔细看过Bellman_ford算法,就没写出来,看完Bellman_Ford之后发现这就是一个模板题,把求最短距离改成求最大概率即可。当前点到达起始概率小于从某节点中转即更新概率。
代码:
#include<stdio.h> #include<string.h> #define N 10010 #define M 50010 #define INF -999.999 int u[M],v[M],next[M],que[M]; double w[M]; int m,n; double dis[N]; int book[N],first[N]; void Bellman_ford() { int i,j,k,tail,head; memset(dis,INF,sizeof(dis)); memset(book,0,sizeof(book)); memset(que,0,sizeof(que)); tail=head=1; dis[1]=1; // for(i=1;i<=n;i++) // printf("%lf*",dis[i]); // printf("\n"); que[head]=1; book[1]=1; tail++; while(head<tail) { k=first[que[head]]; while(k!=-1) { if(dis[v[k]]<dis[u[k]]*w[k]) { dis[v[k]]=dis[u[k]]*w[k]; if(book[v[k]]==0) { book[v[k]]=1; que[tail]=v[k]; tail++; } } k=next[k]; } book[que[head]]=0; head++; } printf("%lf\n",dis[n]*100); } int main() { int i,j,c,a,b,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(u,0,sizeof(u)); memset(v,0,sizeof(v)); memset(w,0,sizeof(w)); memset(next,0,sizeof(next)); for(i=0;i<=n;i++) first[i]=-1; j=1; for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); u[j]=a; v[j]=b; w[j]=c*0.01; next[j]=first[u[j]]; first[u[j]]=j; // printf("%d %d %lf\n",u[j],v[j],w[j]); j++; u[j]=b; v[j]=a; w[j]=c*0.01; next[j]=first[u[j]]; first[u[j]]=j; // printf("%d %d %lf\n",u[j],v[j],w[j]); j++; } Bellman_ford(); } return 0; }