套用Dijstra算法求解。
因为概率是越乘越小,而我们要求最大的。
而路程是越加越长,我们要求最短的。
所以可以套用最短路贪心算法。
但是求最长路就不能用套最短路算法,而要边权取负,同加一个数为正这种方法。
// q.c
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int M=10000;
int n,m,cnt,head[M+10];
double dis[M+10];
bool done[M+10];
struct Edge {
int u,v,next; double w;
Edge():u(0),v(0),next(-1),w(0) {}
}ed[M*3<<1];
struct Node {
int u; double w;
bool operator < (const Node &A) const {
return w<A.w;
}
};
void add_edge(int a,int b,double c) {
ed[++cnt].u=a,ed[cnt].v=b,ed[cnt].w=c,ed[cnt].next=head[a],head[a]=cnt;
ed[++cnt].u=b,ed[cnt].v=a,ed[cnt].w=c,ed[cnt].next=head[b],head[b]=cnt;
}
void dijstra(int s) {
priority_queue<Node> q;
dis[s]=1.0;
q.push((Node){s,dis[s]});
while(!q.empty()) {
Node p=q.top(); q.pop();
if(done[p.u]) continue;
done[p.u]=true;
for(int i=head[p.u];i!=-1;i=ed[i].next) {
Edge e=ed[i];
if(dis[e.v]<dis[e.u]*e.w) {
dis[e.v]=dis[e.u]*e.w;
q.push((Node){e.v,dis[e.v]});
}
}
}
}
int main() {
freopen("toura.in","r",stdin);
freopen("toura.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
int a,b,c;
while(m--) {
scanf("%d%d%d",&a,&b,&c);
add_edge(a,b,c/100.0);
}
dijstra(1);
printf("%.6lf\n",dis[n]*100);
return 0;
}