题目描述
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
提示
提示:选择路线为 1—>435,概率为 85%*90%*80%=61.2%
来源
作者
河南省2016第九届大学生程序设计竞赛
分析:最短路问题,不容易AC,可以用SPAT最短路
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int MAX = 11000;
struct Node
{
int to;//到达点
double cos;//概率
bool operator < (Node a)const
{
return a.cos > cos;
}
} node,nextNode;
bool v[MAX];
vector<Node>vec[MAX];
int main()
{
int cas,n,m;
scanf("%d",&cas);
while(cas--)
{
memset(v,0,sizeof(v));
for(int i=0; i<MAX; i++)
vec[i].clear();
int star,end;
double cos;
scanf("%d %d",&n,&m);
while(m--)
{
scanf("%d %d %lf",&star,&end,&cos);
node.cos=cos/100;
node.to=end;
vec[star].push_back(node);//无向图,所以都要放入集合
node.to=star;
vec[end].push_back(node);
}
priority_queue<Node>qu;//定义优先队列
node.to=1, node.cos=1.00;//初始化
qu.push(node);//放入队列
while(!qu.empty())
{
node = qu.top();//取出首元素
qu.pop();
if(v[node.to])
continue;
if(node.to == n)//如果到达终点
{
printf("%lf\n",node.cos*100);
break;
}
star =node.to ;
cos =node.cos;
v[star] = true;
for(int i = 0; i < vec[star].size(); i++ )
{
nextNode.to = vec[star][i].to;
nextNode.cos = vec[star][i].cos * cos;
qu.push(nextNode);//把到达点放入队列
}
}
}
return 0;
}
SPFA算法:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 50000 + 10;
const int node = 10000 + 10;
const int INF = 0x3f3f3f3f;
int n, m;
double dist[node];//路径
int vis[node];//标记
struct Data
{
int v;
double cost;
};
vector<Data>E[node];
void SPFA()
{
memset(vis,0,sizeof(vis));
int i,j;
for(i=0; i<=n; i++)
dist[i]=0;//要求最安全的,所以初始化为最不安全的
vis[1]=1;
dist[1]=1;//最开始概率为1
queue<int>que;
while(!que.empty())
que.pop();
que.push(1);
int u;
while(!que.empty())
{
u=que.front();
que.pop();
vis[u]=0;
for(i=0; i<E[u].size(); i++)
{
int v=E[u][i].v;
if(dist[v]<dist[u]*(E[u][i].cost/100))
{
dist[v]=dist[u]*(E[u][i].cost/100);//更新最大值
if(vis[v]==0)
{
que.push(v);
vis[v]=1;
}
}
}
}
}
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n >> m;
for(int i = 0; i <= n; i ++)
E[i].clear();
for(int i = 0; i < m; i++)
{
int u, v;
double s;
cin >> u >> v >> s;
Data tmp;
tmp.v=v;
tmp.cost=s;
E[u].push_back(tmp);
tmp.v=u;
tmp.cost=s;
E[v].push_back(tmp);
}
SPFA();
printf("%.6lf\n",dist[n]*100);
}
return 0;
}