Bellman_fordde 队列优化 信道安全

问题 : 信道安全

时间限制: 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;
}


猜你喜欢

转载自blog.csdn.net/gakki_wpt/article/details/80199671