信道安全
- 描述
- 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
- 來源
題意分析:沒錯,這道題就是求最長路徑,首先用鄰接矩陣會爆內存,用地傑斯特拉的鄰接表做法會超時,就得用SPFA算法
代碼如下:
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Max_N = 10002;
struct Node
{
int v;
double w;
int next;
}edge[100050];
int head[Max_N];
bool vis[Max_N];
double dis[Max_N];
int n,m,num;
void add_edge(int u,int v,double w) //構造鄰接表
{
edge[num].v = v;
edge[num].w = w;
edge[num].next = head[u];
head[u] = num++;
}
double SPFA() //SPFA 算法
{
int u,i,v;
queue<int>Q;
for(i=0;i<=n;i++)
{
dis[i] = - INF;
}
memset(vis,false,sizeof(vis));
dis[1] = 1.0;
vis[1] = true;
Q.push(1);
while(!Q.empty())
{
u = Q.front();
Q.pop();
vis[u] = false;
for(i=head[u];i!=-1;i=edge[i].next)
{
v = edge[i].v;
double w = edge[i].w;
if(dis[v]<dis[u]*w)
{
dis[v] = dis[u] * w;
if(!vis[v])
{
vis[v] = true;
Q.push(v);
}
}
}
} return dis[n];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
num = 0;
int i,j,a,b;
double c;
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%lf",&a,&b,&c);
add_edge(a,b,c/100);
add_edge(b,a,c/100);
}
//SPFA();
printf("%.6lf\n",SPFA()*100);
}
return 0;
}