[HAOI2009] 旅行
套用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; }